较为周全的Asp.net提交验证方案

作者:网络 来源:佚名 更新时间:2008-10-15 02:02:14 点击:
下面要对这个生成的“提交验证”类进行功能扩展,通过.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,再以此获取对应的验证码即可开始生成工作。
以下是页面提交的代码:



应用效果:









数据库数据: