2009-04-04 10 views
1

ここで明白な問題は、更新時にボタンイベントが呼び出され、重複した投稿がデータベースに作成されることです。私はこのサイトについて、まったく同じ問題について他の質問を読んだ。Asp.Netボタンリフレッシュ時のイベントが再び発生しますか? GUID?

明らかに答えはすべての投稿についてGUIDを作成し、GUIDが一意であることを確認しますか?私はこれをどのように実装するのか本当にわかりません。

リフレッシュすると、同じGUIDの重複した投稿を作成しようとしますか?

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

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

答えて

1

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

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

Guidは重複する可能性が低いため、使用するのに適しています。 Randomクラスが生成することができる31ビットの乱数も重複を与える可能性はほとんどありませんが、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)を使用します。

1

ここに私が使用するRefreshValidatorコントロールがあります。あなたのページにドロップして、データベースに保存する前にPage.IsValidをチェックしてください。他のバリデータのようにエラーメッセージを追加したり、何か特別なことをしたい場合は、Refreshedイベントをキャッチしたりすることができます。バリデーターなので、GridViewsなどはすでに削除操作やキャンセル操作(グリッドビューもあります)を除いて既に通知されます。

コードはかなりシンプルです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 
関連する問題