Post

如何区分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。 如下图:

Flow Chart

This post is licensed under CC BY 4.0 by the author.