|
以前也研究過,始終沒找到好的辦法,看了微軟Msdn上的解決方案,使用后發現存在較多漏洞,考慮的情況太少,如頁面加載后沒有提交,始終刷新,在同一瀏覽器打開多個各選項卡,每個選項卡打開同一頁面或不同頁面,以下是我的解決方案,
Code
public class RefreshServe : System.Web.UI.Page
{
private static ILog log = LogManager.GetLogger(typeof(RefreshServe));
private readonly string REFRESH_TICKET_NAME = "__RefreshTicketArray";
private readonly string HIDDEN_FIELD_NAME = "__RefreshHiddenField";
private readonly string HIDDEN_PAGE_GUID = "__RefreshPageGuid";
/// <summary>
/// 為True表示頁面刷新,False為正常提交
/// </summary>
public bool IsPageRefreshed
{
get
{
if (IsPostBack && !CheckRefreshFlag())
{
log.Debug("刷新了頁面");
return true;
}
else
{
log.Debug("正常提交");
return false;
}
}
}
/// <summary>
/// 呈現前更新標識
/// </summary>
/// <param name="e"></param>
protected override void OnPreRender(EventArgs e)
{
log.Debug("執行OnPreRender");
base.OnPreRender(e);
UpdateRefreshFlag();
}
/// <summary>
/// 更新標識,正常提交都刪除該次提交的時間,并生產當前新的時間
/// </summary>
private void UpdateRefreshFlag()
{
#region Cookie模式
//注冊頁面唯一標識并返回
string pageGuid = SetCurPageGuid();
HttpCookie cookie = GetRefreshTicket();
if (cookie.Values.Count > 0)
{
cookie.Values.Remove(pageGuid);
log.Debug("當前清除的cookie變是:" + pageGuid);
}
string submitTime = DateTime.Now.ToString("hhmmss.fffff");
//當前提交時間保存到隱藏域
ClientScript.RegisterHiddenField(HIDDEN_FIELD_NAME, submitTime);
log.Debug("即將要新增的時間:submitTime:" + submitTime + " Guid:" + pageGuid.ToString());
cookie.Values.Add(pageGuid, submitTime);
log.Debug("UpdateRefreshFlag中當前Cookie中存在的記錄數為:" + cookie.Values.Count);
for (int i = 0; i < cookie.Values.Count; i++)
log.Info("cookie[" + cookie.Values.GetKey(i) + "]:" + cookie.Values[i]);
Response.AppendCookie(cookie);
#endregion
}
/// <summary>
/// 驗證是否刷新
/// </summary>
/// <returns></returns>
private bool CheckRefreshFlag()
{
HttpCookie cookie = GetRefreshTicket();
string pageGuid = GetCurPageGuid();
if (cookie.Values.Count > 0)
{
bool flag;
if (cookie.Values[pageGuid] != null)
flag = cookie.Values[pageGuid].IndexOf(GetCurSubmitTime()) > -1;
else
flag = true;//防止出現異常,總是可以提交
if (flag)
log.Debug("提交時間存在,可以提交");
else
log.Debug("無效的提交時間");
return flag;
}
return true;
}
/// <summary>
/// 得到已保存的提交時間,沒有新建,有返回
/// </summary>
/// <returns></returns>
private HttpCookie GetRefreshTicket()
{
#region Cookie模式,返回值為Cookie
HttpCookie cookie;
if (Request.Cookies[REFRESH_TICKET_NAME] == null)
{
cookie = new HttpCookie(REFRESH_TICKET_NAME);
Response.AppendCookie(cookie);
log.Debug("Cookie不存在,初始化");
}
else
{
cookie = Request.Cookies[REFRESH_TICKET_NAME];
log.Debug("讀取已存在的Cookie,當前Cookie中存在的記錄數為:" + cookie.Values.Count + "具體有如下幾條:");
for (int i = 0; i < cookie.Values.Count; i++)
log.Info("cookie[" + cookie.Values.GetKey(i) + "]:" + cookie.Values[i]);
}
return cookie;
#endregion
}
/// <summary>
/// 獲取當前提交時間
/// </summary>
/// <returns></returns>
private string GetCurSubmitTime()
{
string submitTime = Request.Params[HIDDEN_FIELD_NAME] == null ? "" : Request.Params[HIDDEN_FIELD_NAME].ToString();
log.Debug("執行GetCurSubmitTime:submitTime為:" + submitTime);
return submitTime;
}
/// <summary>
/// 設置頁面唯一標識,通過Guid標識來區分每個頁面自己的提交時間
/// </summary>
private string SetCurPageGuid()
{
string guid;
if (!IsPostBack)
{
if (Request.Params[HIDDEN_PAGE_GUID] == null)
{
guid = System.Guid.NewGuid().ToString();
log.Debug("SetCurPageGuid注冊了一個新的標識:" + guid);
}
else
guid = GetCurPageGuid();
}
else
{
guid = GetCurPageGuid();
}
ClientScript.RegisterHiddenField(HIDDEN_PAGE_GUID, guid);
return guid;
}
/// <summary>
/// 得到當前頁面的唯一標識
/// </summary>
/// <returns></returns>
private string GetCurPageGuid()
{
string pageGuid = Request.Params[HIDDEN_PAGE_GUID] == null ? "none" : Request.Params[HIDDEN_PAGE_GUID].ToString();
log.Debug("執行GetCurPageGuid()后Page_GUID為:" + pageGuid);
return pageGuid;
}
}
NET技術:徹底解決刷新重復提交問題,你還在用Response.Redirect嗎?,轉載需保留來源!
鄭重聲明:本文版權歸原作者所有,轉載文章僅為傳播更多信息之目的,如作者信息標記有誤,請第一時間聯系我們修改或刪除,多謝。