Asp.Net防止刷新重復(fù)提交數(shù)據(jù)的辦法
在網(wǎng)上搜 一下,可以找到很多關(guān)于這方面的資料,其中有一篇是來自MSDN上的一種解決方法: http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnvs05/html/BedrockASPNET.asp 它是通過重新定義 System.Web.UI.Page 類來實(shí)現(xiàn)加載頁面時(shí),是“刷新”、“后退”請求,還是正常請求,其他的頁面則繼承了自定義的這 個(gè)Page類。感覺他這個(gè)方法比較獨(dú)特,有例子可以下載,有興趣的可以研究研究。
網(wǎng)上最多的解決此類問題的方法就是不保存緩存,即提交后表單上的數(shù)據(jù)不會被瀏覽器的緩存保存,如果此時(shí)再遇到刷新或者后退請求時(shí), 就會顯示“網(wǎng)頁已過期”,數(shù)據(jù)也就不會重復(fù)提交了,這就起到了阻止刷新重復(fù)提交的效果。
下面以簡單的提交一篇帖子為例,介紹禁用緩存防止刷新重復(fù)提交的方法,表單數(shù)據(jù)包括“標(biāo)題”和“正文”兩個(gè)部分。
以下是該方法的代碼(post.aspx):
//頁面加載
protected void Page_Load(object sender, EventArgs e)
{
//可以在頁面加載時(shí)設(shè)置頁面的緩存為“SetNoStore()”,即無緩存
Response.Cache.SetNoStore();
//Session中存儲的變量“IsSubmit”是標(biāo)記是否提交成功的
if ((bool)Session["IsSubmit"])
{
//如果表單數(shù)據(jù)提交成功,就設(shè)“Session["IsSubmit"]”為false
Session["IsSubmit"] = false;
//顯示提交成功信息
ShowMsg.Text = " * 提交成功!";
}
else
//否則的話(沒有提交,或者是頁面刷新),不顯示任何信息
ShowMsg.Text = "";
}
//提交按鈕(btnOK)單擊事件
protected void btnOK_Click(object sender, EventArgs e)
{
if (txtTitle.Text.ToString().Trim() == "")
//ShowMsg是用來顯示提示信息的
ShowMsg.Text = " * 標(biāo)題不能為空!";
else if (txtText.Text.ToString().Trim() == "")
ShowMsg.Text = " * 內(nèi)容不能為空!";
else
{
//這里是將數(shù)據(jù)提交到數(shù)據(jù)庫中,省略
/*
string sql = "insert into tab...values(...)";
MyConn.ExecQuery(sql);
*/
//提交成功后,設(shè)“Session["IsSubmit"]”為true
Session["IsSubmit"] = true;
//強(qiáng)制轉(zhuǎn)換頁面(不可少,否則刷新仍會重復(fù)提交,仍轉(zhuǎn)到本頁),
通過頁面的轉(zhuǎn)換將緩存中的提交的數(shù)據(jù)都釋放了,即提交的標(biāo)單數(shù)據(jù)不會被保存到緩存里,
如果后退的話,將會出現(xiàn)該頁無法顯示
Response.Redirect("post.aspx");
}
}
上面這個(gè)方法非常簡單也很實(shí)用,推薦大家使用。
下面是我自己研究出來的另一種方法,該方法不同于“不保存緩存的方法”,它是讓瀏覽器保存所有頁面緩存的。該方法通過隨機(jī)碼的方式 來判斷是正常提交還是“刷新”或“后退”的。
首先(提交頁面是post.aspx)在 Session 中 增加變量 Rnd 用來存放隨機(jī)碼,同時(shí)在提交表單數(shù)據(jù)時(shí)不做處理,而是讓頁面轉(zhuǎn)到 post.aspx?r=x,這里“x”等于Session["Rnd"],這個(gè)時(shí)候在頁面加載時(shí),通過判斷r的值和Session["Rnd"]的值是否相同,如果相同就處理提 交的數(shù)據(jù),否則即可認(rèn)為是“刷新”或者是“后退”操作了,最后再次付給Session["Rnd"]一個(gè)隨機(jī)碼。
以下是該方法代碼(post.aspx):
//獲取隨機(jī)碼
public class MyRnd
{
public static string Rnd()
{
//隨機(jī)碼是由 0-9 a-z A-Z 之間的數(shù)字或字母組成的
//下面是生成的20位隨機(jī)碼
//0..9 A..Z a..z
//48-57 65-90 97-122
string rst = "";
Random rr = new Random();
for (int i = 0; i < 20; i++)
{
int ir = 0;
do
{
ir = rr.Next(123);
if((ir >= 48) && (ir <= 57)) break;
else if((ir >= 65) && (ir <= 90)) break;
else if ((ir >= 97) && (ir <= 122)) break;
}
while (true);
rst += ((char)ir).ToString();
}
return rst;
}
}
//頁面加載
protected void Page_Load(object sender, EventArgs e)
{
//獲取URL中請求的“r”值,如果“r”不存在則 r=""
string r = "";
if(Request.QueryString["r"] != null)
r = Request.QueryString["r"].ToString().Trim();
string t;
//獲取 “Session” 中的 “Rnd” 值,用于和“r”比較
t = Session["Rnd"].ToString().Trim();
//如果“r=t”則為提交操作,即可對表單的數(shù)據(jù)進(jìn)行處理
if(r == t)
{
if (txtTitle.Text.ToString().Trim() == "")
ShowMsg.Text = " * 標(biāo)題不能為空!";
else if (txtText.Text.ToString().Trim() == "")
ShowMsg.Text = " * 內(nèi)容不能為空!";
else {
//這里是將數(shù)據(jù)提交到數(shù)據(jù)庫中,省略
/*
string sql = "insert into tab...values(...)";
MyConn.ExecQuery(sql);
*/
//提交成功后清空表單數(shù)據(jù)
txtTitle.Text = "";
txtText.Text = "";
//顯示提交成功信息
ShowMsg.Text = " * 提交成功!";
}
}
//否則可以認(rèn)為是“刷新”或者“后退”操作
else
{
txtTitle.Text = "";
txtText.Text = "";
}
//最后要重新獲得“Session["Rnd"]”的值,并將“btnOK.PostBackUrl”設(shè)為“Session["Rnd"]”的值
Session["Rnd"] = MyRnd.Rnd();
btnOK.PostBackUrl ="post.aspx?r=" + Session["Rnd"].ToString().Trim();
}
//這里提交按鈕(btnOK)單擊事件就不需要寫任何代碼了
通過這種方法,每次加載頁面時(shí)“Session["Rnd"]”都將得到一個(gè)新的值,而在刷新或后退時(shí)就不會得到相同的“r”和“t”值,數(shù)據(jù)也就 不會被重復(fù)提交,只有通過“btnOK”來提交的操作才會得到“r==t”,數(shù)據(jù)才會被提交處理的,通過判斷隨機(jī)碼的方式來阻止刷新重復(fù)提交就 可以實(shí)現(xiàn)了。
相關(guān)文章
.NET運(yùn)行界面上,實(shí)現(xiàn)隨意拖動控件的方法
.NET運(yùn)行界面上,實(shí)現(xiàn)隨意拖動控件的方法,需要的朋友可以參考一下2013-03-03
.NET Core跨平臺串口通訊使用SerialPortStream基礎(chǔ)類庫問題解決
這篇文章介紹了.NET Core跨平臺串口通訊使用SerialPortStream基礎(chǔ)類庫問題解決,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2022-01-01
輕量級ORM框架Dapper應(yīng)用之實(shí)現(xiàn)CURD操作
這篇文章介紹了使用Dapper實(shí)現(xiàn)CURD操作的方法,文中通過示例代碼介紹的非常詳細(xì)。對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-03-03
ASP.NET開發(fā)者使用jQuery應(yīng)該了解的幾件事情
如果你是有著APS.NET開發(fā)背景的人員,那么jQuery的幾個(gè)概念建議你應(yīng)該忘掉。像使用其它的framework一樣,你應(yīng)該學(xué)習(xí)一下jQuery的所有語法等約定來讓它更好的為你服務(wù)。2009-09-09
一個(gè)ASP.Net下的WebShell實(shí)例
一個(gè)ASP.Net下的WebShell,主要完成cmd命令。一般的服務(wù)器設(shè)置,asp.net用戶的權(quán)限都比較高。如果asp的webshell無法執(zhí)行,可能asp.net的可以執(zhí)行。2013-07-07
.NET?中的線程安全數(shù)據(jù)結(jié)構(gòu)詳解
.NET提供了多種線程安全的數(shù)據(jù)結(jié)構(gòu),適用于不同的場景,本篇將介紹它們的簡單使用以及在.NETCore和.NET Framework中的可用性,感興趣的朋友一起看看吧2024-12-12
ASP.NET中用js取CheckBoxList中值的方法實(shí)例
用腳本取CheckBoxList中的值,并用"|"將其分開,之后將取到的值放入文本框,返回?cái)?shù)據(jù)庫做添加或者修改2013-07-07

