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 注册一个 HiddenFieldSession 中的Ticket 比较,确定是否是 Refresh 的办法。这个办法用到了 IHttpModule HttpContext,在 IHttpModule.Init(HttpApplication context) 时把是否是 Refresh 的属性放在 HttpContext 中,供整个Page 的生命周期 (LifeCycle) 使用。和这个方法的想法,差不多,下面是一个比较简便的实现方法。

SessionViewState 的特定 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中的KeyViewState中的Key (上次的ViewState)不相同,则认为是 F5 刷新。如果是相同的则说明用了最后RenderSession KeyViewState Key所以被认为是Html DomFormSubmit。 如下图:

Flow Chart

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