Thursday, September 23, 2010

Easy solution to refresh the page due to duplication of data submission problems

Performed postback operation of web pages to refresh when the browser will have a "not to re-send a message, you can not refresh the page" message, if it had just executed exactly to the database to insert a new record of operations, point [again] The result is inserted into the two duplicate records, it has always been with the saved data back turned to the current page methods to solve, recently found a new way.


Analysis
In the System.Web.UI.Page class, there is a page named ViewState property to save the current view state to observe the end of each aspx page html code generated can be found, in fact, added to the page called __VIEWSTATE hidden field, and its value is the same as the page's current state of each execution postback, after the value the value will change, and refresh the page do not change. For this, we can execute code in the page at the end of the current write a Session in ViewState, and when a page loads is to determine whether the current Session ViewState value is equal (in fact, is exactly the value of ViewState Session of the previous state ), if so, it is a normal postback, if the same is to refresh the browser, so that, as long as our data into the code if outside the nest a judge can achieve the purpose of preventing the duplication of data submitted.


In fact, the problem here has not been fully resolved, specifically the key issues is the Session. Assume that we will save ViewState this.Session ["myViewState"], if a user opens the same time to submit two anti refresh the page to a mess, and that the url for the page Set Session of the key it? Does not work, because the user may open in two windows the same page, it must be defined for each open page only Session key, and the key can be saved along with the current page instance, reference ViewState is saved, directly to the page we add a hidden field specialized storage Session keys on it. 


The oop80 and Edward.Net reminder, to the extent possible, reduce the Session data server resources usage, now the program slightly adjusted, the ViewState using md5 encrypted and returned to the 32-bit string to the Session.


In addition, because this method will generate an additional Session occupy server resources, so please keep the current page to the circumstances under which state, if the current page without the need to retain state, directly after the completion of the data submitted can be redirected to the current page. 
SubmitOncePage
SubmitOncePage is for the above analysis written by an inherited from the System.Web.UI.Page base class, the need to prevent refresh the repeated submission of data pages from the base class, the source code is as follows: 
 namespace myControl 
 ( 
 / /   
 / / / Name: SubmitOncePage 
 / / / Parent: System.Web.UI.Page 
 / / / Description: The address data caused the browser to refresh the page to submit questions repeated extension classes. 
 / / / Example: if (! This.IsRefreshed) 
 / / / ( 
 / / / / / Specific code 
 / / /) 
 / / / Original: Cong Xing Zi (cncxz) E-mail: cncxz@126.com 
 / / /  

     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"); 
 ) 

 ) 
 )
Test Project
First SubmitOncePage class compiled into a single source dll, and then test the following steps:
1, a new asp.net web application; 2, add SubmitOncePage class corresponds to the dll reference; 3, add a Label control to the webform1 (Label1) and a Button control (Button1); 4, set Label1's Text 0; 5, double-click Button1 to codebehind view; 6, to modify the parent class WebForm1 class SubmitOncePage and add the test code, the results are as follows:
 public   class WebForm1: myControl.SubmitOncePage 
 ( 
 protected System.Web.UI.WebControls.Label Label1; 
 protected System.Web.UI.WebControls.Button Button1; 


 Web Form Designer generated code 
         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 (); 
 ) 
 ) 

& Am, p; nb, sp; 7, press F5 to run, in the browser window in a row a few clicks Button1, and then refresh the page several times, and then a few clicks Button1; 8, corresponding to the test project directory, open the file a.txt and b.txt can see if (! This.IsRefreshed) the specific effect.

No comments:

Post a Comment