1

ここで明らかな問題は、更新時にボタン イベントがリコールされ、重複した投稿がデータベースに作成されることです。このサイトで、まったく同じ問題について他の質問を読みました。

どうやら答えは、投稿ごとに GUID を作成し、GUID が一意であることを確認することです。これを実装する方法がよくわかりません。

それは更新時に、同じ GUID で重複した投稿を作成しようとすることを意味しますか?

GUID をデータベースにどのように実装しますか? または、これが答えでない場合、何ですか?

ありがとうございました!

4

2 に答える 2

1

これが、私が使用する RefreshValidator コントロールです。ページにドロップして、データベースに保存する前に Page.IsValid を確認してください。他のバリデータと同様にエラー メッセージを追加したり、何か特別なことをしたい場合は Refreshed イベントをキャッチしたりできます。これは Validator であるため、GridViews などは既にそれに注意を払っています - Delete または Cancel アクションを除いて (ええ、私はそれを解決するカスタム 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
于 2009-04-04T02:28:48.197 に答える
1

アイデアは、フォームの一意の番号を作成し、フォームが投稿されたときに、編集/作成しているレコードのデータベースにこの一意の番号を保存することです。保存する前に、その番号が既に使用されているかどうかを確認してください。その場合、それは更新によって再投稿されたフォームです。

レコードを更新する場合は、そのレコードが同じ一意の番号で保存されているかどうかを確認するだけで済みますが、新しいレコードを追加する場合は、他のレコードにその番号があるかどうかを確認する必要があります。

Guid は、重複する可能性が非常に低いため、使用するのに適した番号です。クラスが生成できる31 ビットの乱数Randomも重複する可能性はほとんどありませんが、Guid の 128 ビットにより、重複する可能性ははるかに低くなります。

データベースに Guid 値を作成する必要はありませんGuid.NewGuid()。フォームを初期化するコードで使用するだけです。フォームの非表示フィールドに Guid を配置できます。データベースでは、Guid 値を格納できるフィールド (使用可能な場合は Guid データ型、または Guid のテキスト表現を保持するのに十分な大きさのテキスト フィールド) だけが必要です。

このメソッドを使用してToString、Guid 値の文字列表現を取得できます (フォームに入れることができます)。を使用id.ToString("N")すると、最もコンパクトな形式、つまりセパレータなしの 32 桁の 16 進数が得られます。を使用id.ToString("B")すると、より認識しやすい形式 "{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}" が得られます。文字列 (いずれかの形式) から Guid を取得するには、単に を使用しますnew Guid(str)

于 2009-04-04T01:17:09.757 に答える