上篇

下面要对这个生成的“提交验证”类进行功能扩展,通过.Net的“部分类”或“扩展方法”技术都可以轻松实现,这里采用的是“部分类”技术:

引用生成的ADO.NET Entity Framework数据模型的命名空间,且声明为部分类。

书写静态构造函数及一个静态属性:

static 提交验证()

{

   过期时间差值=3;

}

 

/// <summary>

/// 用于计算过期时间,单位为分钟

/// </summary>

public static double 过期时间差值

{

    get

    {

        return _过期时间差值;

    }

    set

    {

        _过期时间差值=value;

    }

}

private static double _过期时间差值;

书写添加验证信息的方法:

/// <summary>

/// 添加一个新的验证信息,注意在此前应为Session中的任意变量赋值,否则SessionID将随机变化,无法通过验证

/// </summary>

/// <param name="验证码">要保存的验证码</param>

/// <returns>验证信息ID</returns>

public static Guid 添加(string 验证码)

{

    var a = new 提交验证

    {

        ID = Guid.NewGuid(),

        会话ID = HttpContext.Current.Session.SessionID,

        是否已提交 = false,

        验证码 = 验证码,

        过期时间 = DateTime.Now.AddMinutes(过期时间差值)

    };

    using (CommonDBEntities c=new CommonDBEntities())

    {

        c.AddTo提交验证(a);

        c.SaveChanges();

    }

    return a.ID;

}

此方法将返回添加的验证信息的GUID,需注意的是在执行此方法之前,必须曾为Session赋值过,未赋值的话SessionID将是随机的,这会让后面的验证函数认为客户端被劫持。

获取验证信息的方法:

/// <summary>

/// 通过ID获取验证信息

/// </summary>

/// <param name="ID">验证信息ID</param>

/// <returns>验证信息</returns>

public static 提交验证 获取(Guid ID)

{

    try

    {

        提交验证 a;

        using (CommonDBEntities c = new CommonDBEntities())

        {

            a = c.提交验证.First(f => f.ID == ID);

        }

        return a;

    }

    catch { return null; }

}

验证用户提交信息的方法:

/// <summary>

/// 验证用户输入的验证码是否正确

/// </summary>

/// <param name="ID">验证信息ID</param>

/// <param name="验证码">用户输入的验证码</param>

/// <returns>返回错误信息,如验证成功则返回null</returns>

public static string 验证(Guid ID, string 验证码)

{

    var 验证信息 = 提交验证.获取(ID);

    if (验证信息 == null) return "验证信息无效或已过期";

    else if (验证信息.过期时间 < DateTime.Now) return "验证信息已过期";

    else if (验证信息.是否已提交) return "信息已被提交过";

    else if (验证信息.会话ID.Trim() != HttpContext.Current.Session.SessionID) return "验证信息被非法劫持";

    else if (验证信息.验证码.Trim().ToLower() != 验证码.ToLower()) return "验证码错误";

    else return null;

}

标记已提交信息及清理超时信息的方法:

/// <summary>

/// 将指定ID的验证信息设为已提交

/// </summary>

/// <param name="ID">验证信息ID</param>

public static void 设为已提交(Guid ID)

{

    using (CommonDBEntities c = new CommonDBEntities())

    {

        var a = c.提交验证.First(f => f.ID == ID);

        a.是否已提交 = true;

        c.SaveChanges();

    }

    清理(false);

}

 

/// <summary>

/// 清理数据库中已失效的旧数据

/// </summary>

/// <param name="是否清理已提交的数据">是否连带清理已提交过的数据,否则只清理过期数据</param>

/// <returns>波及的数据总量</returns>

public static int 清理(bool 是否清理已提交的数据)

{

    int x = 0;

    using (CommonDBEntities c = new CommonDBEntities())

    {

        var a = c.提交验证.Where(f => f.过期时间 < DateTime.Now || (是否清理已提交的数据 ? f.是否已提交 : false));

        foreach (提交验证 f in a)

        {

            c.DeleteObject(f);

        }

        x=c.SaveChanges();

    }

    return x;

}

在设置已提交的方法中顺手清理超时信息。

至此,验证类就编写完成了。

接下来看看如何使用,先创建一个这样的页面:


如前所述,验证信息ID会明文发给客户端,即保存在HiddenField控件中。

CustomValidator用于显示错误提示。

以下为页面Load事件的代码:


注意在调用添加验证信息的函数之前设置过了Session的变量,确保SessionID不会再发生改变。

关于生成验证图片的代码到处都是,这里就不累述了,只要通过Url参数“ID”获取到GUID,再以此获取对应的验证码即可开始生成工作。

以下是页面提交的代码:


应用效果:




数据库数据:


本文至此结束,希望能给各位以帮助,如有更好的解决方案,欢迎在此探讨。

下载本文的PDF版本:http://www.box.net/shared/dtisa6mik8

转载此文章时须注明转载自”SkyD(斯克迪亚)开发者博客“,并保留此文章的Url链接

作者信息

昵称
斯克迪亚

查看其所发布的所有文章

总积分
2420
注册时间
(2018年5月4日 19:06)

评论

目前还没有任何评论。

[切换到移动版页面]