【问题标题】:SqlDataReader always read as falseSqlDataReader 总是读为 false
【发布时间】:2017-05-07 04:13:00
【问题描述】:

我无法弄清楚为什么这个函数会导致错误,即使它看起来是正确的。

这并没有错。有什么解决办法吗?

连接字符串或 SQL 相关函数没有问题。我的功能有问题。我使用 SQL Server。

ESEMKABank > Employee:

EmployeeId    int IDENTITY(1, 1)
Username      nvarchar(64)
Password      nvarchar(64)
FullName      nvarchar(64)
RoleId        int                     -- <-- FOREIGN KEY

对于 VB.NET:

Imports System.Data.SqlClient

Public Class Form_Login

    'Dimensions
    Dim theConnection As New SqlConnection
    Dim theCommand As New SqlCommand
    Dim theDataReader As SqlDataReader
    Dim theDataAdapter As New SqlDataAdapter

    'Initialization
    Private Sub Form_Login_Load(sender As Object, e As EventArgs) Handles Me.Load
        theConnection.ConnectionString = "SERVER = MORGAN\SQLEXPRESS; DATABASE = ESEMKABank; INTEGRATED SECURITY = TRUE;"

        'Parameterize
        theCommand.Parameters.Add("@Username", SqlDbType.VarChar).Value = Me.TextBox_Username.Text
        theCommand.Parameters.Add("@Password", SqlDbType.VarChar).Value = Me.TextBox_Password.Text

    End Sub

    'Login
    Private Sub Button_Login_Click(sender As Object, e As EventArgs) Handles Button_Login.Click
        If Me.TextBox_Username.Text = "" Or Me.TextBox_Password.Text = "" Then
            Me.PictureBox_Wrong.Visible = True
        Else
            Using theDataReader

                'Declaration
                theCommand.Connection = theConnection
                theCommand.CommandText = "SELECT Username, Password FROM Employee WHERE Username = @Username AND Password = @Password"
                theConnection.Open()
                theDataReader = theCommand.ExecuteReader()

                If theDataReader.Read() Then

                    'Dispose!
                    theCommand.Dispose()
                    theConnection.Close()
                    SqlConnection.ClearPool(theConnection)

                    Me.PictureBox_Wrong.Visible = False
                Else

                    'Dispose!
                    theCommand.Dispose()
                    theConnection.Close()
                    SqlConnection.ClearPool(theConnection)

                    Me.PictureBox_Wrong.Visible = True
                End If
            End Using
        End If

    End Sub

End Class

【问题讨论】:

  • 您可以尝试将查询替换为“SELECT 1”吗?只是作为一个测试
  • 好吧让我试试
  • 结果是 = 错误。

标签: sql-server vb.net visual-studio


【解决方案1】:

不要在 Form_Load 中设置参数值。在这一点上,它们只是空字符串。在设置.CommandText 属性之后设置参数值。

当我在这里时,假设用户在第一次尝试时输错了密码。此代码将在第二次尝试时总是失败 - 即使他们已更正密码 - 因为您已释放连接。在 .Net 中,最佳做法是在大多数情况下使用全新的连接对象(也包含在 Using 块中),这样您就可以避免此类问题并利用连接池。

最后,这段代码意味着您以纯文本形式存储密码,而不是使用加盐哈希。这是非常令人难以置信的错误,我什至不会留下显示其他修复的示例代码,因为我不想留下执行用户名/密码检查的示例,让其他人看到不涉及哈希密码。

【讨论】:

  • 已修复大声笑问题。谢谢。
  • 不是全部问题。
  • 阅读我回答中的第二两段。
  • 不要在 Class 中声明 Dim?
  • 是的,您应该重新声明这些对象。是的,那里有一些开销,但同样:它比额外的网络延迟要低得多。至于参数......它们减轻了一种类型的攻击。它们很重要。你绝对应该使用它们。但您也不应该永远以纯文本形式存储密码。要存储密码,您需要预先添加一个唯一的(每个用户)salt 并以加密方式(即:不是 md5 或 sha1;您想要 bcrypt 或 scrypt)对结果进行哈希处理,然后将其存储。当有人尝试登录时,您对尝试的密码执行相同的操作并比较哈希值。
猜你喜欢
  • 1970-01-01
  • 2014-12-27
  • 1970-01-01
  • 2013-12-18
  • 2022-01-26
  • 1970-01-01
  • 2013-12-25
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多