【问题标题】:Invalid attempt to access a field before calling Read() vb.NET and MySQL在调用 Read() vb.NET 和 MySQL 之前访问字段的尝试无效
【发布时间】:2015-12-29 16:55:12
【问题描述】:

每次我尝试使用不正确的详细信息登录时都会收到此错误,该错误应该显示一个消息框“无效的用户名...”,当没有输入任何详细信息时,它应该显示“请输入...

    conn = New MySqlConnection
    conn.ConnectionString = "server=localhost; userid=root; password=...; database=..."
    Dim reader As MySqlDataReader

    Try
        conn.Open()
        Dim Query As String
        Query = "SELECT Username, Password, Admin FROM appointments.tblLogin WHERE Username='" & TextBox_Username.Text & "' AND Password='" & TextBox_Password.Text & "' "
        cmd = New MySqlCommand(Query, conn)
        reader = cmd.ExecuteReader

        Dim count As Integer
        count = 0
        While reader.Read
            count = count + 1
        End While

        If reader.GetInt32("Admin") = 1 Then
            AdminMainMenu.Show()
            Me.Hide()
        ElseIf reader.GetInt32("Admin") = 0 Then
            MainMenu.Show()
            Me.Hide()
        Else
            MessageBox.Show("Invalid username or password")
        End If

        If TextBox_Username.Text.Equals("") And TextBox_Password.Text.Equals("") Then
            MessageBox.Show("Please enter a username and password")
        End If

        conn.Close()

    Catch ex As MySqlException
        MessageBox.Show(ex.GetBaseException.ToString)
    Finally
        conn.Dispose()
    End Try

【问题讨论】:

    标签: mysql vb.net


    【解决方案1】:

    MySqlDataReader 只能向前移动,一旦到达命令检索到的行的末尾,就不能返回读取之前的行。
    用于计算行数的循环将读取器移动到数据流的末尾。因此,尝试读取 Admin 字段会导致异常。

    If TextBox_Username.Text.Equals("") And _
       TextBox_Password.Text.Equals("") Then
        MessageBox.Show("Please enter a username and password")
       Return
    End If
    
    .... opening and executing the command code....
    
    If reader.Read Then
        Dim isAdmin = (reader.GetInt32("Admin") = 1)
        If isAdmin Then
           AdminMainMenu.Show()
           Me.Hide()
        Else Then
           MainMenu.Show()
           Me.Hide()
        End If
    Else 
        MessageBox.Show("Invalid username or password")
    End If
    conn.Close()
    

    请注意,我已经删除了循环并在 Read 方法周围使用了一个简单的 if/else 语句来显示错误消息,并且我已经更改了 Admin 标志的读取,创建了一个布尔变量以简化真实部分中的逻辑if 块。

    也就是说,您需要查看如何构建参数化查询,因为构建命令文本的字符串连接会将您的程序暴露给 Sql 注入攻击(更不用说语法错误,如果您的某些文本框包含单引号,试试吧.. .)

    还要考虑从安全的角度来看,您永远不应该将密码以明文形式存储在数据库中。始终使用密码的哈希值

    【讨论】:

    • 稍微整理了一下,谢谢大家的帮助。但是它不会显示错误消息,也不会显示消息框。
    • 感谢您的帮助!是的,所有的安全和验证都使用正则表达式等。我打算稍后再做,我想在处理诸如散列和停止 sql 注入攻击等细节之前完成所有核心编码。你知道有什么好的网站或类似的学习散列和构建参数化查询的网站吗?
    • 没有比这个更好的了。使用搜索框。而且,作为新用户,我建议您阅读How does accepting an answer works
    • '我认为这是参数化查询吗? cmd = New MySqlCommand(Query, conn) cmd.Parameters.AddWithValue("@username", TextBox_Username2.Text) cmd.Parameters.AddWithValue("@password", TextBox_Password2.Text) cmd.Parameters.AddWithValue("@firstName", TextBox_Forename.Text) cmd.Parameters.AddWithValue("@surname", TextBox_Surname.Text) cmd.Parameters.AddWithValue("@telephoneNo", TextBox_TeleNo.Text)
    • 是的,但忘记了 AddWithValue。这是一个等待抓住你的陷阱。见Can we stop using AddWithValue already?,是关于Sql Server的,但是概念是一样的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-03
    • 1970-01-01
    相关资源
    最近更新 更多