2010-03-24 50 views
1

爲了防止重複的請求(即在點擊命令按鈕後立即按下F5),我設置了我的頁面基類,以便在檢測到重複請求時忽略該請求。如何在不清除瀏覽器的情況下忽略一個http請求?

當我說「忽略」我的意思是到Response.End()

現在,我想我以前看過這部作品,其中有一個問題,我剛纔到Response.End()和用戶頁面少了點沒有。我不知道這種情況的確切情況,但我現在無法重複。

現在,當我調用Response.End(),我只是得到一個空的瀏覽器。更具體地說,我得到這個HTML。

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> 
<HTML><HEAD> 
<META http-equiv=Content-Type content="text/html; charset=utf-8"></HEAD> 
<BODY></BODY></HTML> 

我設置了以下測試應用程序以確認問題不在我的應用程序的其他地方。那就是:

以下內容添加到一個aspx形式

<asp:Label ID="lbl" Text="0" runat="server" /><br /> 
<asp:Button ID="btnAdd1" Text="Add 1" runat="server" /><br /> 
<asp:Button ID="btnAdd2" Text="Add 2" runat="server" /><br /> 
<asp:Button ID="btnAdd3" Text="Add 3" runat="server" /><br /> 

而這裏的代碼隱藏文件

using System; 

namespace TestDupRequestCancellation 
{ 
public partial class _Default : System.Web.UI.Page 
{ 
    protected void Page_Init(object sender, EventArgs e) 
    { 
    btnAdd1.Click += btnAdd1_Click; 
    btnAdd2.Click += btnAdd2_Click; 
    btnAdd3.Click += btnAdd3_Click; 
    } 

    protected void Page_Load(object sender, EventArgs e) 
    { 
    if (!IsPostBack) 
    CurrentValue = 0; 
    else if (Int32.Parse(lbl.Text) != CurrentValue) 
    Response.End(); 
    } 

    protected void Page_PreRender(object sender, EventArgs e) 
    { 
    lbl.Text = CurrentValue.ToString(); 
    } 

    protected int CurrentValue 
    { 
    get 
    { 
    return Int32.Parse(Session["CurrentValue"].ToString()); 
    } 
    set 
    { 
    Session["CurrentValue"] = value.ToString(); 
    } 
    } 

    void btnAdd3_Click(object sender, EventArgs e) 
    { 
    CurrentValue += 3; 
    } 

    void btnAdd2_Click(object sender, EventArgs e) 
    { 
    CurrentValue += 2; 
    } 

    void btnAdd1_Click(object sender, EventArgs e) 
    { 
    CurrentValue += 1; 
    } 
} 
} 

當加載頁面,點擊任意按鈕並期望是什麼,但如果您在按下其中一個按鈕之後隨時按下F5鍵,則會將其檢測爲重複請求並調用Response.End(),以及時結束該任務。這使用戶留下了空白的瀏覽器。

有沒有辦法讓用戶在頁面上保持原樣,所以他們只需點擊一個按鈕?

另外;請注意,這段代碼是我可以用來展示我的問題的最簡單的代碼。這並不是要演示如何檢查dup請求。

編輯:另一個改變,將允許我實現相同的結果將是禁用所有我的事件處理程序。那可能嗎?

回答

1

如果您在執行事件之前檢查驗證程序,那麼連接到您的驗證功能可能是實現此目的最無干擾的方式。

試試這個:

using System; 
using System.Web.UI.WebControls; 

namespace TestDupRequestCancellation 
{ 
    public partial class _Default : System.Web.UI.Page 
    { 
     protected void Page_Init(object sender, EventArgs e) 
     { 
      btnAdd1.Click += btnAdd1_Click; 
      btnAdd2.Click += btnAdd2_Click; 
      btnAdd3.Click += btnAdd3_Click; 
      AddFirstPostbackValidator(); 
     } 

     protected void Page_Load(object sender, EventArgs e) 
     { 
      if (!IsPostBack) 
       CurrentValue = 0; 
     } 

     protected void Page_PreRender(object sender, EventArgs e) 
     { 
      lbl.Text = CurrentValue.ToString(); 
     } 

     protected int CurrentValue 
     { 
      get 
      { 
       return Int32.Parse(Session["CurrentValue"].ToString()); 
      } 
      set 
      { 
       Session["CurrentValue"] = value.ToString(); 
      } 
     } 

     private void AddFirstPostbackValidator() 
     { 
      CustomValidator val = new CustomValidator(); 
      val.ID = "DuplicatePostbackValidator"; 
      val.ErrorMessage = "Browser refresh detected. Command ignored."; 
      val.ServerValidate += val_ServerValidate; 
      Validators.Add(val); 
      form1.Controls.AddAt(form1.Controls.IndexOf(lbl) + 1, val); // user feedback 
     } 

     void val_ServerValidate(object source, ServerValidateEventArgs args) 
     { 
      args.IsValid = Int32.Parse(lbl.Text) == CurrentValue; 
     } 

     void btnAdd3_Click(object sender, EventArgs e) 
     { 
      if (!IsValid) 
       return; 
      CurrentValue += 3; 
     } 

     void btnAdd2_Click(object sender, EventArgs e) 
     { 
      if (!IsValid) 
       return; 
      CurrentValue += 2; 
     } 

     void btnAdd1_Click(object sender, EventArgs e) 
     { 
      if (!IsValid) 
       return; 
      CurrentValue += 1; 
     } 
    } 
} 
+0

這將允許我阻止事件的執行。謝謝。 – 2010-03-25 19:57:20

0

不要強制響應結束。讓它順利地結束(通過),而不需要通過合法請求的「主要」邏輯。如果這證明工作太多,那麼你的代碼可能需要重構。或者,懶惰的出路,你可以設置一個全局布爾值來指示請求的有效性(在Page_Load中設置),然後根據需要在整個剩餘代碼中檢查它。

編輯

我越思考這個,我更偏向於一個更人性化的做法。如何將他們重定向到一個專門告知他們如何避免重複請求的網頁?這是我的銀行網站所做的。

+0

我可以從每一個事件處理程序檢查,而是想辦法從基類這樣做,因爲unintrusively越好。我正在考慮關閉所有的事件處理程序,但我不確定可以做到......可以嗎? – 2010-03-24 20:44:43

+0

@Timid請閱讀我的編輯。對不起:) – 2010-03-24 20:50:09

+0

謝謝,只要我得到足夠的代表,我會盡快給你一個贊成票。 – 2010-03-24 21:09:25

0

看看發送HTTP響應代碼204 No Content做你想做的。

+0

這也沒有工作。不管怎麼說,還是要謝謝你。 – 2010-03-25 19:55:42

相關問題