这里显而易见的问题是,刷新时会调用按钮事件,并在数据库中创建重复的帖子。我在本网站上已经阅读了有关同一问题的其他问题。
显然答案是每个帖子创建一个GUID并检查以确保GUID是唯一的?我不确定如何实现这一点。
这是否意味着在刷新时,它会尝试创建具有相同GUID的重复帖子?
如何在数据库中实现GUID?或者,如果这不是答案,那是什么?
谢谢!
答案 0 :(得分:1)
您的想法是为表单创建唯一编号,并在发布表单时将此唯一编号保存在您正在编辑/创建的记录的数据库中。在保存之前,请检查是否已使用该号码,在这种情况下,它是一个已通过刷新重新发布的表单。
如果要更新记录,则只需检查该记录是否已使用相同的唯一编号保存,但如果要添加新记录,则必须检查是否有其他记录具有该编号。
Guid是一个很好用的数字,因为你不太可能得到重复。 Random
类可以产生的31位随机数也不太可能产生重复,但是Guid的128位使得它更不可能。
您不必在数据库中创建Guid值,只需在初始化表单的代码中使用Guid.NewGuid()
即可。您可以将Guid放在表单中的隐藏字段中。在数据库中,您只需要一个可以存储Guid值的字段,可以是Guid数据类型(如果可用),也可以只是一个足以容纳Guid文本表示的文本字段。
您可以使用ToString
方法获取Guid值的字符串表示形式(以便您可以将其放在表单中)。使用id.ToString("N")
提供最紧凑的格式,即没有分隔符的32个十六进制数字。使用id.ToString("B")
提供更易识别的格式“{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}”。要从字符串(格式)中恢复Guid,只需使用new Guid(str)
。
答案 1 :(得分:1)
这是我使用的RefreshValidator控件。只需将其放在页面上,并在保存到数据库之前检查Page.IsValid。您可以像其他验证器一样添加错误消息,或者如果要执行特殊操作,请捕获刷新事件。由于它是一个验证器,GridViews等已经注意到了它 - 除了删除或取消操作(是的,我有一个自定义的GridView也能解决这个问题......)
代码非常简单 - 将GUID存储到ControlState中,并将副本存储在Session中。在加载时,比较2.如果它们不相同 - 那么它就是刷新。冲洗,重复并创建一个新的GUID并重新开始。
''' <summary>
''' A validator control that detects if the page has been refreshed
''' </summary>
''' <remarks>If <see cref="SessionState.HttpSessionState" /> is not available or is reset, validator will return Valid</remarks>
Public Class RefreshValidator
Inherits BaseValidator
Private isRefreshed As Boolean
Protected Overrides Sub OnInit(ByVal e As System.EventArgs)
MyBase.OnInit(e)
Page.RegisterRequiresControlState(Me)
End Sub
Protected Overrides Function SaveControlState() As Object
Dim obj As Object = MyBase.SaveControlState()
Return New System.Web.UI.Pair(_pageHashValue, obj)
End Function
Protected Overrides Sub LoadControlState(ByVal savedState As Object)
Dim pair As System.Web.UI.Pair = TryCast(savedState, System.Web.UI.Pair)
If pair IsNot Nothing Then
_pageHashValue = TryCast(pair.First, String)
MyBase.LoadControlState(pair.Second)
Else
MyBase.LoadControlState(savedState)
End If
End Sub
Private _pageHashValue As String
Protected Overrides Sub OnLoad(ByVal e As System.EventArgs)
MyBase.OnLoad(e)
If HttpContext.Current Is Nothing OrElse HttpContext.Current.Session Is Nothing Then
isRefreshed = False
Return
End If
' Get hash value from session
Dim currHashValue As String = CType(HttpContext.Current.Session(Me.UniqueID & ":pageHashValue"), String)
If _pageHashValue Is Nothing OrElse currHashValue Is Nothing Then
' No page hash value - must be first render
' No current hash value. Session reset?
isRefreshed = False
ElseIf currHashValue = _pageHashValue Then
' Everything OK
isRefreshed = False
Else
' Was refreshed
isRefreshed = True
End If
' Build new values for form hash
Dim newHashValue As String = Guid.NewGuid().ToString()
_pageHashValue = newHashValue
HttpContext.Current.Session(Me.UniqueID & ":pageHashValue") = newHashValue
End Sub
Protected Overrides Function ControlPropertiesValid() As Boolean
Return True
End Function
Protected Overrides Function EvaluateIsValid() As Boolean
If isRefreshed Then OnRefreshed(EventArgs.Empty)
Return Not isRefreshed
End Function
Protected Overridable Sub OnRefreshed(ByVal e As EventArgs)
RaiseEvent Refreshed(Me, e)
End Sub
''' <summary>
''' Fires when page is detected as a refresh
''' </summary>
Public Event Refreshed As EventHandler
End Class