ASP.NET防止頁面重新整理的兩種解決方案小結_實用技巧

來源:互聯網
上載者:User

方法有二,總結如下:

第一方法:
直接在CS代碼裡敲:
Response.Buffer = true;
Response.ExpiresAbsolute = DateTime.Now.AddSeconds(-1);
Response.Expires = 0;
Response.CacheControl = "no-cache";

當有人想按後退時頁面已到期,效果就達到了

第二方法:
SubmitOncePage:解決重新整理頁面造成的資料重複提交問題(網上資料)

執行過postback操作的web頁面在重新整理的時候,瀏覽器會有“不重新發送資訊,則無法重新整理網頁”的提示,若剛剛執行的恰好是往資料庫插入一條新記錄的操作,點[重試]的結果是插入了兩條重複的記錄,以前一直是用儲存資料後重新轉向當前頁面的方法解決,最近又找到了一個新的方法。

問題分析

在System.Web.UI.Page類中,有一個名為ViewState屬性用以儲存頁面的當前檢視狀態,觀察每個aspx頁面最終產生的html代碼可以發現,其實就是向頁面添加了一個名為__VIEWSTATE的隱藏欄位,其value值就是頁面的目前狀態,每次執行postback過後,該 value值都會發生變化,而重新整理頁面則不會改變。

針對這種情況,我們可以在頁面代碼執行的末尾將當前的ViewState寫到一個Session中,而在頁面載入時則判斷該Session值是否與當前 ViewState相等(其實Session值恰好是ViewState的前一狀態),若不等,則是正常的postback,若是相等則是瀏覽器重新整理,這樣一來,只要在我們的資料插入代碼外嵌套一個if判斷就可以達到防止資料重複提交的目的了。

其實到這裡問題還沒有完全解決,具體說來就是Session的索引值問題。假設我們將ViewState儲存為 this.Session["myViewState"],如果一個使用者同時開啟兩個防重新整理提交的頁面就亂套了,那針對頁面的url設定Session的索引值呢?還是不行,因為使用者有可能在兩個視窗中開啟同一頁面,所以必須為每次開啟的頁面定義唯一的Session索引值,並且該索引值可以隨當前頁面執行個體一起儲存,參考ViewState的儲存方式,我們直接向頁面添加一個隱藏欄位專門存放Session索引值就可以了。

經oop80和Edward.Net的提醒,為了儘可能地降低Session資料對伺服器資源的佔用量,現將上述方案略做調整,將ViewState利用md5加密後返回的32位字串寫入Session。

另外,由於本方法會產生額外的Session佔用伺服器資源,所以請在必須保留當前頁面狀態的情況下使用,若無需保留當前頁面狀態,則在完成資料提交後直接重新導向到當前頁面即可。

SubmitOncePage

SubmitOncePage是針對上述分析寫的一個繼承自System.Web.UI.Page的基類,需要防止重新整理重複提交資料的頁面從該基類繼承,源碼如下:

複製代碼 代碼如下:

namespace myControl
{
/// <summary>
/// 名稱:SubmitOncePage
/// 父類:System.Web.UI.Page
/// 描述:解決瀏覽器重新整理造成的資料重複提交問題的page擴充類。
/// 樣本:if (!this.IsRefreshed)
///{
/////具體代碼
///}
/// </summary>
public class SubmitOncePage:System.Web.UI.Page
{
private string _strSessionKey;
private string _hiddenfieldName;
private string _strLastViewstate;

public SubmitOncePage()
{
_hiddenfieldName = "__LastVIEWSTATE_SessionKey";
_strSessionKey = System.Guid.NewGuid().ToString();
_strLastViewstate = string.Empty;
}

public bool IsRefreshed
{
get
{
string str1 = GetSessinContent();
_strLastViewstate = str1;
string str2 = this.Session[GetSessinKey()] as string;
bool flag1 = (str1 != null) && (str2 != null) && (str1 == str2);
return flag1;
}
}

protected override void Render(System.Web.UI.HtmlTextWriter writer)
{
string str = GetSessinKey();
this.Session[str] = _strLastViewstate;
this.RegisterHiddenField(_hiddenfieldName, str);
base.Render(writer);
}


private string GetSessinKey()
{
string str = this.Request.Form[_hiddenfieldName];
return (str == null) ? _strSessionKey : str;
}

private string GetSessinContent() {
string str = this.Request.Form["__VIEWSTATE"];
if (str == null) {
return null;
}
return System.Web.Security.FormsAuthentication.HashPasswordForStoringInConfigFile(str, "MD5");
}

}
}


測試專案

首先將SubmitOncePage類的源碼編譯成一個單獨的dll,然後進行測試,步驟如下:

1、建立一個asp.net web應用程式;
2、添加SubmitOncePage類對應的dll引用;
3、給webform1添加一個Label控制項(Label1)和一個Button控制項(Button1);
4、設定Label1的Text為0;
5、雙擊Button1轉到codebehind視圖;
6、修改類WebForm1的父類為SubmitOncePage並添加測試代碼,結果如下:

複製代碼 代碼如下:

public class WebForm1 : myControl.SubmitOncePage
{
protected System.Web.UI.WebControls.Label Label1;
protected System.Web.UI.WebControls.Button Button1;


#region Web Form設計器產生的程式碼
override protected void OnInit(EventArgs e)
{
//
// CODEGEN: 該調用是 ASP.NET Web Form設計器所必需的。
//
InitializeComponent();
base.OnInit(e);
}

/// <summary>
/// 設計器支援所需的方法 - 不要使用代碼編輯器修改
/// 此方法的內容。
/// </summary>
private void InitializeComponent()
{
this.Button1.Click += new System.EventHandler(this.Button1_Click);
}
#endregion

private void Button1_Click(object sender, System.EventArgs e)
{
int i=int.Parse(Label1.Text)+1;
Label1.Text = i.ToString();
if (!this.IsRefreshed)
{
WriteFile("a.txt", i.ToString());
}
WriteFile("b.txt", i.ToString()); 


}

private void WriteFile(string strFileName,string strContent)
{
string str = this.Server.MapPath(strFileName); 
System.IO.StreamWriter sw = System.IO.File.AppendText(str);
sw.WriteLine(strContent);
sw.Flush();
sw.Close(); 
}
}


7、按F5運行,在瀏覽器視窗中連續點擊幾次Button1,然後重新整理幾次頁面,再點擊幾次Button1;

8、轉到測試專案對應目錄下,開啟a.txt和b.txt檔案,可看到if (!this.IsRefreshed) 的具體效果。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.