接上篇。
下面要對這個產生的“提交驗證”類進行功能擴充,通過.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