下面要对这个生成的“提交验证”类进行功能扩展,通过.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,再以此获取对应的验证码即可开始生成工作。
以下是页面提交的代码:
应用效果:
数据库数据: