2

これには本当に困惑しています。

ユーザーがアプリを使用する前に自分のアカウントを作成する必要があるアプリを構築するための仕様を提供していました。

仕様によると、ユーザーの電子メールは、データベースにある電子メールに対して検証する必要があります。

そのメールが既に存在する場合は、ユーザーに通知し、別のメールを選択するように依頼します。

以下は、そのすべてを行うコードです。

//マークアップ:

<tr>
   <td height="27" width="129"><font face="Tahoma" size="2">
   <label for="txtEmail">Your Email address:</label></font></td>
   <td height="27" width="244">
     <asp:TextBox ID="txtEmail" CssClass="Treb10Blue" Runat="server"  style="font-family: Trebuchet MS; font-size: 10pt; font-weight: bold; font-style: italic; color: #000080;"></asp:TextBox>
     <asp:RequiredFieldValidator ID="RequiredFieldValidator4" Runat="server" ErrorMessage="*" Display="Dynamic" ControlToValidate="txtEmail"></asp:RequiredFieldValidator>
     <asp:RegularExpressionValidator ID="RegularExpressionValidator1" ControlToValidate="txtEmail" ValidationExpression=".*@.*\..*" ErrorMessage="Email not in correct format" Display="Dynamic" Runat="server"></asp:RegularExpressionValidator>
   </td>
</tr>

//その後、コードビハインド

Function Fixquotes(ByVal thesqlenemy As String) As String
    Fixquotes = Replace(thesqlenemy, "'", "''")
End Function

Sub btnRegister_Onclick(ByVal Src As Object, ByVal e As System.Web.UI.ImageClickEventArgs)
    If Page.IsValid Then
        Dim objConn As IDbConnection = New SqlConnection(ConfigurationManager.ConnectionStrings("DBConnectionString").ConnectionString)
        Dim chkUsername As IDbCommand
        Dim addUser As IDbCommand
        Dim strSQL1 As String
        Dim strSQL2 As String
        Dim strUserCount As Integer

    'first, check if user already exists
        Try
            strSQL1 = "SELECT COUNT(*) FROM [tblLogin] WHERE [Email]='" & Fixquotes(txtEmail.Text) & "'"
            strSQL2 = "INSERT INTO [tblLogin] ([Fullname], [Email], [Username], [Password],[Rights],[ModifiedDate],Precinct,PositionId,ProcessedFlag)"
            strSQL2 = strSQL2 & " VALUES "
            strSQL2 = strSQL2 & "('" & Fixquotes(txtFullname.Text) & "', '" & Fixquotes(txtEmail.Text) & "', '" & Fixquotes(txtUsername.Text) & "', '" & Fixquotes(txtPassword.Text) & "',2,getdate(), '" & precinctList.SelectedValue & "'," & PosisitionList.SelectedValue & ",'No')"
            'Response.Write(strSQL2)
            'Response.End()
            objConn.Open()
            chkUsername = New SqlCommand(strSQL1, objConn)
            strUserCount = chkUsername.ExecuteScalar()
            If strUserCount = 0 Then
                addUser = New SqlCommand(strSQL2, objConn)
                addUser.ExecuteNonQuery()
                objConn.Close()
                'Display some feedback to the user to let them know it was sent
                lblMsg.ForeColor = System.Drawing.Color.Green
                lblMsg.Text = "Your account has been successfully created.<br><br>Please click the Close button below to close this window and log in with your newly created username and password."


                'Clear the form
                txtFullname.Text = ""
                txtEmail.Text = ""

            Else
                lblMsg.Text = "That email address already exists. Please choose another..."
                lblMsg.ForeColor = Drawing.Color.Red
            End If
        Catch

            objConn.Close()

        End Try
    End If
End Sub

これまでに、サインアップした合計 1,035 人のユーザーのうち、9 人が同じメール アドレスを使用して重複したアカウントを作成できました。

それらのユーザーの 1 人はそれを 5 回実行しました。

これはどのように可能であり、それ以上の発生を防ぐにはどうすればよいですか?

事前にどうもありがとう

4

3 に答える 3

2

おそらく、非常に短い間隔でリクエストが発生し、クエリが実行される間に、値が一意ではなくなります。すべてをトランザクションにカプセル化すると、これを防ぐことができます。プラクティスが進む限り、それをストアド プロシージャに入れることを検討する必要があります。

于 2013-10-02T19:25:07.253 に答える
1

はい、可能ですが、5回は難しいようです。おそらく、ユーザーがダブルクリックしたため、コードが 2 回実行されました。現在、クエリが存在するかどうかを確認してから作成するまでに一定の時間がかかるため、複数のクエリを作成することができます。

これを修正するには、いくつかの方法があります。

コードでトランザクションを実装することを確認できますTransactionScope

SQL SQL トランザクションでトランザクションを実装できます

または、私のお気に入りは、トランザクションの方法で SQL を記述します。両方の SQL ステートメントを、"IF NOT EXISTS(SELECT TOP 1 1 FROM [tblLogin] WHERE [Email]='" & Fixquotes(txtEmail.Text) で始まる 1 つの文字列に入れます。 ) & "' " & YourInsertSqlHere

次に、ExecuteNonQuery() を使用してこの SQL を実行すると、結果が保持されます。0 の場合は、既に存在するために挿入されなかったことを意味します。

ただし、最初に、他の操作を行う前に、クリックしたときにボタンを無効にして、ダブルクリックの問題を修正してください!

于 2013-10-02T19:24:45.840 に答える
1

重複エントリを停止する 1 つの方法は、データベース テーブルUNIQUEの列に制約を設定して、重複データがデータベースに入るのを停止することです。[Email]

次に、少なくとも、重複INSERT試行が発生したときに例外がスローされます。

于 2013-10-02T19:14:19.497 に答える