用户如何能够创建重复的帐户?

时间:2013-10-02 19:08:44

标签: asp.net vb.net

我对此感到非常困惑。

我们提供了一个规范来构建一个应用程序,要求用户在使用该应用程序之前创建自己的帐户。

规范说用户的电子邮件应该根据他/她在我们数据库中的电子邮件进行验证。

如果该电子邮件已存在,请通知用户并让他/她选择其他电子邮件。

以下是执行所有操作的代码。

//标记:

<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)名用户可以使用SAME电子邮件地址创建重复的帐户。

其中一位用户做了5次!

这怎么可能,如何防止进一步发生?

提前多多感谢

3 个答案:

答案 0 :(得分:2)

您可能会非常快速地发出请求,并且在执行查询之间的时间内,该值不再是唯一的。封装事务中的所有内容会阻止这种情况,并且就实践而言,您应该考虑将其放入存储过程中。

答案 1 :(得分:1)

停止重复条目的一种方法是通过在数据库表中的UNIQUE列上放置[Email]约束来阻止重复数据进入数据库。

然后,至少在发生重复的INSERT尝试时会抛出异常。

答案 2 :(得分:1)

是的,这是可能的,但5次似乎很难做到。用户双击的可能性很大,导致代码运行两次。现在,因为查询之间有一段时间来查看它是否存在以及创建它的时间,所以可以创建倍数。

要解决这个问题,有几种方法。

您可以在代码TransactionScope

中查看实施交易

您可以在SQL SQL Transaction

中实现交易

或者,我最喜欢的是,以一种跨行的方式编写SQL 将两个SQL语句放入1个以“IF NOT EXISTS(SELECT TOP 1 1 FROM [tblLogin] WHERE [Email] ='”&amp; Fixquotes(txtEmail.Text)&amp;“'”&amp; YourInsertSqlHere

开头的字符串中

然后,当您使用ExecuteNonQuery()运行此SQL时,保留结果,如果为0,则表示它没有插入,因为它已经存在。

但首先,在您执行任何其他操作之前,通过在单击按钮时禁用按钮来修复双击问题!