如何区分PostBack是F5刷新还是FormSubmit
在一个页面上有很多 Button 或者可以提交的 Html Dom 对象,如何区分服务器端收到的 PostBack 是用户点击的 FromSubmit 还是 F5 页面刷新。在 http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnvs05/html/BedrockASPNET.asp 这篇文章的 Trap the Browser Refresh 部分讲述了一个办法,用 Page.RegisterHiddenField 注册一个 HiddenField 和 Session 中的Ticket 比较,确定是否是 Refresh 的办法。这个办法用到了 IHttpModule HttpContext,在 IHttpModule.Init(HttpApplication context) 时把是否是 Refresh 的属性放在 HttpContext 中,供整个Page 的生命周期 (LifeCycle) 使用。和这个方法的想法,差不多,下面是一个比较简便的实现方法。
用 Session 和 ViewState 的特定 Key 比较检查是否是刷新。每次 OnPreRender 后再次重新发号。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
public partial class F5 : System.Web.UI.Page
{
private static string MaskKey = "____MASKKEY"; //注册全局的MaskKey
protected void Page_Load(object sender, EventArgs e)
{
ShowStatus();//打印状态
}
private void InitialMask()
{
this.Session[MaskKey] = this.ViewState[MaskKey] = Guid.NewGuid().ToString();//重新发号 给Session 和 ViewState 新的Guid Session在服务器端标志 ViewState放在客户端标志
}
protected override void OnPreRender(EventArgs e)
{
base.OnPreRender(e);
InitialMask();//发号
}
public bool IsRefresh
{
get
{
if (this.Session[MaskKey] == null || this.ViewState[MaskKey] == null) return false;
return !this.Session[MaskKey].ToString().Equals(this.ViewState[MaskKey].ToString());//检查Key是否相同
}
}
protected void btnTest_Click(object sender, EventArgs e)
{
this.lblGuid.Text = this.Session[MaskKey].ToString() + " " + this.ViewState[MaskKey].ToString();//打印Key
}
private void ShowStatus()
{
if (this.IsRefresh)
{
this.lblShow.Text = "F5 Refresh";
}
else
{
this.lblShow.Text = "Html Dom submit";
}
}
}
IE 的 F5 Refresh 提交的是IE中最后一次对服务器的请求,也就是上的ViewState中的东西,由于没有使用Html Dom来提交,没有提交这次新发的ViewState Key。这样Session中的Key和ViewState中的Key (上次的ViewState)不相同,则认为是 F5 刷新。如果是相同的则说明用了最后Render的 Session Key和ViewState Key所以被认为是Html Dom的FormSubmit。 如下图:
