ASP.NETページのリフレッシュを防ぐ2つの解決策のまとめ

5193 ワード

方法は二つあり、以下にまとめる.
第一方法:直接CSコードの中で叩く:Response.Buffer = true; Response.ExpiresAbsolute = DateTime.Now.AddSeconds(-1); Response.Expires = 0; Response.CacheControl = "no-cache";
後退を押すとページが期限切れになり、効果が得られます.
第2の方法:SubmitOncePage:ページのリフレッシュによるデータ重複コミットの問題(ネット上の資料)を解決する
postback操作を実行したウェブページがリフレッシュされると、ブラウザでは「情報を再送信しないとページをリフレッシュできない」というメッセージが表示されます.ちょうどデータベースに新しいレコードを挿入する操作を実行していたら、「再試行」の結果、2つの重複レコードが挿入され、以前はデータを保存してから現在のページに再転向する方法で解決されていましたが、最近は新しい方法が見つかりました.
もんだいぶんせき
システムでWeb.UI.Pageクラスには、ページの現在のビュー状態を保存するためにView Stateという名前のプロパティがあり、aspxページごとに最終的に生成されるhtmlコードを観察すると、ページに__という名前が追加されていることがわかります.VIEWSTATEの非表示ドメインは、そのvalue値がページの現在の状態であり、postbackを実行するたびにそのvalue値が変化し、ページのリフレッシュは変化しません.
この場合、現在のViewStateをページコード実行の最後に1つのセッションに書き込むことができ、ページロード時にそのセッション値が現在のViewStateと等しいか否か(実際にはセッション値はちょうどViewStateの前の状態である)を判断し、等しくなければ通常のpostbackであり、等しくなければブラウザリフレッシュである.私たちのデータ挿入コードの外にif判断をネストすれば、データの重複コミットを防止する目的を達成することができます.
実はここまで問題はまだ完全に解決されていません.具体的にはSessionのキー値の問題です.ビューステートをthisとして保存するとします.Session["myView State"]では、1人のユーザーが同時に2つのリフレッシュ防止コミットページを開くと混乱しますが、ページのurlに対してSessionのキー値を設定しますか?やはりだめです.ユーザーは2つのウィンドウで同じページを開く可能性があるので、開くたびに唯一のSessionキー値を定義しなければなりません.このキー値は現在のページインスタンスとともに保存できます.ViewStateの保存方法を参照して、ページに非表示ドメインを追加してSessionキー値を保存すればいいです.
oop 80とEdward.Netのアラートは、サーバリソースに対するSessionデータの使用量をできるだけ低減するために、上記のスキームを少し調整し、md 5暗号化によってViewStateが返した32ビット文字列をSessionに書き込む.
また、本方法ではサーバリソースを使用する追加のセッションが生成されるので、現在のページステータスを保持する必要がある場合に使用し、現在のページステータスを保持する必要がない場合は、データのコミットが完了した後、直接現在のページにリダイレクトすればよい.
SubmitOncePage
SubmitOncePageは、上述の分析について書かれたシステムから継承する.Web.UI.Pageのベースクラスは、繰り返しコミットされたデータをリフレッシュするページがそのベースクラスから継承されることを防止する必要があります.ソースコードは以下の通りです.
 
  
namespace myControl
{
///
/// :SubmitOncePage
/// :System.Web.UI.Page
/// : page 。
/// :if (!this.IsRefreshed)
///{
/////
///}
///

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を新規作成する.Netwebアプリケーション;2、SubmitOncePageクラスに対応するdll参照を追加する.3、webform 1にLabelコントロール(Label 1)とButtonコントロール(Button 1)を追加する.4、Label 1のTextを0に設定する.5、Button 1をダブルクリックしてcodebehindビューに移動する.6.クラスWebForm 1の親をSubmitOncePageに変更し、テストコードを追加した結果、以下のようになります.
 
  
public class WebForm1 : myControl.SubmitOncePage
{
protected System.Web.UI.WebControls.Label Label1;
protected System.Web.UI.WebControls.Button Button1;


#region Web
override protected void OnInit(EventArgs e)
{
//
// CODEGEN: ASP.NET Web 。
//
InitializeComponent();
base.OnInit(e);
}

///


/// -
/// 。
///

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、F 5を押して運行して、ブラウザのウィンドウの中で連続的に何回Button 1をクリックして、それから何回のページをリフレッシュして、更に何回Button 1をクリックします;
8、テスト項目対応ディレクトリに移動し、a.txtとb.txtファイルを開き、if(!this.IsRefreshed)の具体的な効果を見ることができます.