2009-04-04 2 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를 선택하십시오. 다른 유효성 검사기와 같은 오류 메시지를 추가하거나 특별한 작업을 수행하려는 경우 새로 고침 이벤트를 잡을 수 있습니다. 유효성 검사기이므로 GridViews 등에서 이미 삭제 또는 취소 작업 (예, GridView도 해당 문제를 해결할 수 있습니다 ...)을 제외하고 이미주의를 기울입니다.

코드는 매우 간단합니다. GUID를 ControlState에 저장하고 세션의 복사본을 저장합니다. 적재시에 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 
관련 문제