处理 ASP.NET 浏览器刷新






2.21/5 (11投票s)
2007年6月27日
3分钟阅读

61289

215
本文介绍了一种相对简单的方法来区分 ASP.NET 中的回发请求和用户浏览器生成的请求
引言
多年来,大多数 ASP.NET 开发人员都遇到过这样的情况:点击浏览器的刷新按钮或按 F5 键会执行与 .NET 代码上次执行的步骤完全相同的步骤。 简单来说,让我们创建一个场景,我有一个 ASP.NET 应用程序,它有一个名为“添加客户”的表单。 此表单上有一个按钮,当用户单击该按钮时,会将一个客户添加到文件中。 如果用户再次点击“添加客户”按钮,则会将另一个客户添加到文件中。 但是,如果用户此时按下刷新按钮或按 F5 键,则会重复完全相同的场景,并且还会添加一个客户。 因此,在 ASP.NET 中,无论何时点击 F5,.NET 都会重复其上次操作。 即使 F5 事件不是真正的回发事件,也会发生这种情况。 无需赘述,开发人员希望摆脱这种情况。
背景
我的同事几天前也遇到了同样的问题。 我们在互联网上进行了大量搜索,找到了一些解决方案,但这些解决方案要么只是伪代码(即无法正常工作),要么就像是反复试验。 其中一些直接跳过了脑袋。 不幸的是,没有一种解决方案可以很容易地在 ASP.NET 中实现并证明其合理性。
在互联网上搜索了两天后,我偶然发现了一条小线索,虽然我不记得出处了。 它建议我们可以区分真正的回发请求和浏览器刷新生成的请求。 所有在回发时触发的服务器端事件也会在刷新时触发,但幸运的是,存在一个事件,onsubmit
,它仅在存在真正的回发请求时触发。 它是放置在您的网页上的表单的客户端事件。
使用代码
以下代码的逻辑是在您的 Web 表单上设置一个隐藏控件,并且每次有真正的回发请求时,客户端脚本只是将一个字符附加到该隐藏控件的现有值。 在服务器端,我采用一个共享变量,它将在应用程序的生命周期内保留其值,也就是说,它不会在每次页面加载时被写入。
第一次执行 page_load
事件时,我将共享变量的值分配为 1
。 正如我已经说过的,主要任务是区分真正的回发请求和在“添加客户”按钮上进行的刷新请求。 简单的逻辑是,如果这是第一次执行该事件,那么我的共享变量将是 1
。 如果不是第一次,则隐藏控件的字符长度将比之前的长度大 1。 我可以很容易地从 len(control.value)
中获得控件的新长度。
然后,每次添加客户时,我都将当前控件长度分配给该共享变量。 因此,下次添加客户时,您的长度应比上次的长度大 1。 在每次真正的回发请求时,都会将一个值附加到表单的 onsubmit
事件时调用的客户端脚本中隐藏控件的当前值。
JavaScript
// The JavaScript Function which gets fired on form submit (onsubmit) when
// there is a post back request, and appends a flag value to
// the hidden control
function AddFlag()
{
//on every genuine postback request, we append a value to
// the existing hidden field value
document.getElementById("Flag").value=
document.getElementById("Flag").value + 'P';
}
Visual Basic
'The Server Side VB.Net Class, containing the shared level variable
Partial Class _Default Inherits System.Web.UI.Page
Shared done As String 'The shared variable will retain its
'value through the application's life...
'Page load event to set value to the variable for the first time
Protected Sub Page_Load(ByVal sender As Object,
ByVal e As System.EventArgs) Handles Me.Load
If Not Page.IsPostBack Then 'for the first time
done = 1
End If
End Sub
'The main conditional check in this function
'checks for two things, if the request for
'this event is for the first time then let it go,
'which is pretty obvious, moreover
'if it's not the first time then for a genuine
'postback the current length of characters in
'hidden control should be greater then its previous,
'as on every genuine post back
'request it is appending a value to it, if not then
'it means this request is generated by the
'browser's refresh and hence it would execute the ELSE condition.
Protected Sub AddCustomer_Click(ByVal sender As Object,
ByVal e As System.EventArgs) Handles AddCustomer.Click
'this condition will check either its the first
'time or genuine post back request
If Len(Flag.Value) > Len(done) Or done = "1" Then
'Write Your Add Customer Code here > Response.Write("true")
done = Flag.Value 'substituting variable value
'with the current value of hidden control
Else
Response.Write("false")
End If
End Sub
End Class
关注点
这个解决方案的吸引力在于它没有要求您处理复杂的事情,例如 HTTP 标头、HTTP 模块、从客户端设置会话、在代码和数据库级别保持不必要的检查等。 它也可以应用于用户面临类似问题的任何场景和任何版本的 ASP.NET。 它的解决方案非常简单,即使是刚开始使用该技术的开发人员也可以理解和应用。
历史
- 2007 年 6 月 27 日 -- 发布原始版本