在用ASP。NET 做WEB 窗体时,如果处理反复刷新窗体时导致事件处理错误的问题??
即用户如果点了页面中的某个按钮以后,对该按钮引的事件如果做了处理。如果用户点击IE的“刷新” 按钮,这时候在服务器端还会引发该按钮单击的相同的事件。
这样,就会导至数据的不正确了,即有时候可能会对已经处理过的数据再进行一次处理,会产生很多新的问题,比如数据重复添加之类的。
对于这类问题,各位是怎么处理的呢?
问题点数:0、回复次数:10Top
1 楼llm2002()回复于 2003-06-04 17:08:59 得分 0
一般情况下,添加记录提交后,清空数据,对于提交的信息进行控制,防止空记录提交。
还有象DataGrid等模板那样,显示信息和录入界面不同,提交时将录入界面清空数据,通过显示界面来显示。谁还有什么更好的方法???Top
2 楼wuxk(偷偷的我走了,正如我偷偷的来了)回复于 2003-06-04 18:03:29 得分 0
唉,这一直是一个烦人的事。从WEB开始到现在,对这类问题的解决方案是屡出不穷了。
有人甚至弹出一个没有工具条和屏蔽F5的窗口来了事。各位又是怎么处理的呢?
Top
3 楼dmn(道明牛)回复于 2003-06-05 12:26:16 得分 0
也许可在真正提交时,在URL后(或其它地方)带标志,完成后清空标志,那么刷新时,标志就不存在了.Top
4 楼heian911(网页菜鸟)回复于 2003-06-05 12:34:19 得分 0
也许可以加上如果不是第一次访问该页面 将不执行此程序
Top
5 楼Tom1999(可爱多)回复于 2003-06-06 12:53:46 得分 0
在page_load中,加入if(!post)Top
6 楼wuxk(偷偷的我走了,正如我偷偷的来了)回复于 2003-06-12 16:39:05 得分 0
可爱多:
你说的是postback属性吧,那没用。它和刷新窗体一点儿关系都没有的。
只是表示页面是不是第一次载入。Top
7 楼wuxk(偷偷的我走了,正如我偷偷的来了)回复于 2003-06-12 16:52:26 得分 0
刷新浏览器将上次发送到的数据完全重新发送了一次到服务器,所以任何清空数据都没办法防止。当然可以在做操作前首选检查要操作的数据是不是已经操作过来取消操作,但代价太大了,需要花费很多判断的时间。而且,有的操作是没法判断的。
我是这样解决的,算是解决的刷新的问题,只需要稍改一下就可以用在非ASP.NET的开发技术中去了。
首先在 global.asax 文件中,初始化一个会话变量
Sub Session_Start(ByVal sender As Object, ByVal e As EventArgs)
' 在会话启动时激发
'初始化用来判断用户是否用刷新页面的标记
Session("isRefresh") = "0"
End Sub
然后
text.aspx
<%@ Page Language="vb" AutoEventWireup="false" Codebehind="test.aspx.vb" Inherits="W_BUYER.test"%>
<!-- 注意上面这段声明你需要更改一下 -->
<HTML>
<HEAD>
<title>test</title>
</HEAD>
<body MS_POSITIONING="GridLayout">
<form id="Form1" method="post" runat="server">
<FONT face="宋体">
<asp:Button id="Button1" style="Z-INDEX: 101; LEFT: 173px; POSITION: absolute; TOP: 196px" runat="server" Text="测试一" Width="78px"></asp:Button></FONT>
<asp:Button id="Button2" style="Z-INDEX: 102; LEFT: 301px; POSITION: absolute; TOP: 196px" runat="server" Text="测试二" Width="118px" Height="26px"></asp:Button>
<asp:Label id="Label1" style="Z-INDEX: 103; LEFT: 219px; POSITION: absolute; TOP: 62px" runat="server" Width="344px" Height="27px" Font-Size="Large" ForeColor="Red">单击按钮和浏览器的刷新试试:)</asp:Label>
<input type="hidden" name="isRefresh" id="isRefresh" value='<%=cstr(session("isRefresh"))%>' style="Z-INDEX: 104; LEFT: 3px; POSITION: absolute; TOP: 15px">
</form>
</body>
</HTML>
---------------------------------------------------------------------------------
text.aspx.vb
Imports Components.HickeyTrade.Facility
Public Class test
Inherits System.Web.UI.Page
Protected WithEvents Button2 As System.Web.UI.WebControls.Button
Protected WithEvents Label1 As System.Web.UI.WebControls.Label
Protected WithEvents Button1 As System.Web.UI.WebControls.Button
#Region " Web 窗体设计器生成的代码 "
'该调用是 Web 窗体设计器所必需的。
<System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()
End Sub
Private Sub Page_Init(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Init
'CODEGEN: 此方法调用是 Web 窗体设计器所必需的
'不要使用代码编辑器修改它。
InitializeComponent()
End Sub
#End Region
Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
'在此处放置初始化页的用户代码
End Sub
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
'重新生成是否刷新的随机值
Response.Write("<hr>")
Response.Write("<br>是否刷新? " & RefreshProcess.isRefresh())
End Sub
Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
Response.Write("<hr>")
Response.Write("<br>是否刷新? " & (CStr(Session("isRefresh")) <> Request.Form("isRefresh")))
End Sub
Private Sub Form_OnUnload(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Unload
End Sub
Protected Overrides Sub OnPreRender(ByVal e As System.EventArgs)
RefreshProcess.setRefreshTag()
End Sub
End Class
---------------------------------------------------------------------------------
RefreshProcess.vb
Imports System.Web
Namespace HickeyTrade.Facility
'功能:用来在需要防止用户刷新的页面中判断用户是否点击了刷新按钮
'备注:该类中的 isRefresh方法用来获得用户是否刷新,但是对于页面第一次装入时如果用该方法,则返回的结果
' 也是为 True
'作者:wuxk
'时间:2003年6月9日
Public MustInherit Class RefreshProcess
'功能:设定刷新随机值对的标记,该方法在需要禁止刷新的页面中必须覆盖父类的OnPreRender,像以下所示
' Protected Overrides Sub OnPreRender(ByVal e As System.EventArgs)
' RefreshProcess.setRefreshTag
' End Sub
' 使用该方法的时候必须在页面中嵌入一个隐藏表单,并且值必须如下设置
' <input type="hidden" name="isRefresh" id="isRefresh" value='<%=cstr(session("isRefresh"))%>'>
Public Shared Sub setRefreshTag()
HttpContext.Current.Session("isRefresh") = CStr(New Random(New Random().Next(1, 10000)).Next(1, 10000))
End Sub
'功能:获得用户是否通过刷新来访问该页的,返回的为一个 bool 值
Public Shared Function isRefresh() As Boolean
Return (CStr(HttpContext.Current.Session("isRefresh")) <> HttpContext.Current.Request.Form("isRefresh"))
End Function
End Class
End Namespace
这是我处理刷新的方法,我将它封装到了一个类里,由于需要处理防止刷新的页面并不多,所以用起来也算方便的。
思路就是:在会话变量中保存一个随机值,并将之赋值给隐藏表单中,由于不是由新的页面隐藏表单的值每次都是从服务器上得到的,所以部是和会话变量中的相同,这时,可以认为用户没用刷新页面。否则,将视为用户点击了刷新页面。
但是有个问题,即用户第一次访问页面的时候 隐藏表单的值和服务器上的值是不一致的。但是此时隐藏单的值为空。也可以认为用户没有刷新页面。不过在ASP.NET中,我直接使用页面的 IsPostBack 属性来解决了这个问题。不过页面第一次访问时,通常是不需要限制刷新的,因为没有牵涉到数据的提交。Top
8 楼Jain123(朋克^_^)回复于 2003-06-12 17:02:08 得分 0
学习Top
9 楼mongtze(江南有情天)回复于 2003-06-12 17:05:45 得分 0
重新定向url是一种不太好的解决方法。
即在事件处理完后,
Response.Redirect("./本页面");Top
10 楼wuxk(偷偷的我走了,正如我偷偷的来了)回复于 2003-06-14 17:02:27 得分 0
对,那样会造成不必要的服务器开销,而且。重定向页面也不能解决用户用后退按钮待访问。而我的解决方法则可以防止用户用了后退按钮后的提交。Top



