0

这是我编写的代码,它曾在访问级别显示 System.Data.Dataset 返回,但这不是我想要的。用户名是字符串,密码也是字符串,访问级别是整数。有没有更有效的替代方法?你也能解释一下为什么我会出错,这样我以后就不会遇到类似的事情了。提前致谢

[错误图片和访问打印的内容][1]

Public Class Login
    Dim Access_level As Integer
    Private Sub Login_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        'TODO: This line of code loads data into the 'Parts.User' table. You can move, or remove it, as needed.
        'Me.UserTableAdapter.Fill(Me.Parts.User)
    End Sub
    Public Async Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        If TextBox1.Text = "" Or TextBox2.Text = "" Then
            MsgBox("Oops ¯\_(ツ)_/¯ " + Err.Description(), MsgBoxStyle.OkOnly, "Enter Value")
        Else
            Try
                Await getDataSet(TextBox1.Text, TextBox2.Text, Access_level)
                Print(username)
                Print(password)
                If username = TextBox1.Text And password = TextBox2.Text Then
                    Dim Access As Integer = Access_level
                    Print(Access)
                    If Access = 1 Then
                        Me.Hide()
                        AdminMainMenu.Show()
                    Else
                        Me.Hide()
                        MainMenu.Show()
                    End If
                End If
            Catch ex As Exception
                'MsgBox("Oops " + Err.Description(), MsgBoxStyle.OkOnly, "Failed to Open")
                'MsgBox("Incorrect login details", MsgBoxStyle.OkOnly)
                System.Windows.Forms.MessageBox.Show(ex.Message)
            End Try
        End If
        TextBox1.Clear()
        TextBox2.Clear()
    End Sub

    Public Async Function getDataSet(username As String, password As String, Access_level As Integer) As Task(Of DataSet)
        Return Await Task.Factory.StartNew(
            Function()
                Dim connectionString = "server=localhost; userid=root; password=; database=partstest1; CharSet=utf8;"
                Dim commandText = "SELECT Username, Password, Accesslevel FROM `user` WHERE `Username` = '" & username & "' and `Password` = '" & SHA256(password) & "';"
                Using connDB = New MySqlConnection(connectionString), objCmd = New MySqlCommand(), objAdpt = New MySqlDataAdapter()
                    connDB.Open()
                    objCmd.Connection = connDB
                    objCmd.CommandText = commandText
                    objCmd.CommandType = CommandType.Text
                    objAdpt.SelectCommand = objCmd
                    Dim objDs = New DataSet()
                    objAdpt.Fill(objDs)
                    Console.WriteLine(objDs)
                    Return objDs
                End Using
            End Function)
    End Function


  [1]: https://i.stack.imgur.com/g9CIj.png
4

1 回答 1

1

您不应该需要所有 Async 的东西来检索一条数据。

数据库代码:

您可以将 .CommandText 和命令连接直接传递给命令的构造函数。

您已经有了用户名和密码。不要检索您不需要的数据。

始终使用参数来避免 Sql 注入并使 sql 语句更易于编写。

我假设 Sha256(password) 是一个自定义函数。

CommandType.Text 是默认值,不必明确指定。

您不需要 DataAdapter。您不会在此处更新此数据。无论如何,您的适配器超出了范围,因此没有任何价值。

您不需要数据集。您只处理一个数据,而不是多个表。使用 .ExecuteScalar 返回结果集第一行的第一列。

Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    If TextBox1.Text = "" OrElse TextBox2.Text = "" Then
        MessageBox.Show("Oops ¯\_(ツ)_/¯  both Username and Password must be filled in.", "Enter Value")
        Exit Sub
    End If
    Try
        Access_level = getAccessLevel(TextBox1.Text, TextBox2.Text)
    Catch ex As Exception
        MessageBox.Show(ex.Message)
        Exit Sub
    End Try

    If Access_level = 1 Then
        Me.Hide()
        AdminMainMenu.Show()
    Else
        Me.Hide()
        MainMenu.Show()
    End If
    TextBox1.Clear()
    TextBox2.Clear()
End Sub

Private Function getAccessLevel(username As String, password As String) As Integer
    Dim retVal As Integer
    Dim connectionString = "server=localhost; userid=root; password=; database=partstest1; CharSet=utf8;"
    Using connDB = New MySqlConnection(connectionString),
                    objCmd = New MySqlCommand("SELECT  Accesslevel FROM `user` WHERE `Username` = @Username and `Password` = @Password", connDB)
        objCmd.Parameters.Add("@Username", MySqlDbType.VarChar, 100).Value = username
        objCmd.Parameters.Add("@Password", MySqlDbType.VarChar, 100).Value = SHA256(password)
        connDB.Open()
        retVal = CInt(objCmd.ExecuteScalar())
    End Using
    Return retVal
End Function

编辑

Private Function getAccessLevel(username As String, password As String) As Integer
    Dim retVal As Object
    Dim connectionString = "server=localhost; userid=root; password=; database=partstest1; CharSet=utf8;"
    Using connDB = New MySqlConnection(connectionString),
                objCmd = New MySqlCommand("SELECT  Accesslevel FROM `user` WHERE `Username` = @Username and `Password` = @Password", connDB)
        objCmd.Parameters.Add("@Username", MySqlDbType.VarChar, 100).Value = username
        objCmd.Parameters.Add("@Password", MySqlDbType.VarChar, 100).Value = SHA256(password)
        connDB.Open()
        retVal = objCmd.ExecuteScalar()
    End Using
    If retVal Is Nothing Then
        Return -1
    Else
        Debug.Print(CInt(retVal).ToString)
        Return CInt(retVal)
    End If
End Function

按钮代码...

Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    If TextBox1.Text = "" OrElse TextBox2.Text = "" Then
        MessageBox.Show("Oops ¯\_(ツ)_/¯  both Username and Password must be filled in.", "Enter Value")
        Exit Sub
    End If
    Try
        Access_level = getAccessLevel(TextBox1.Text, TextBox2.Text)
    Catch ex As Exception
        MessageBox.Show(ex.Message)
        Exit Sub
    End Try

    If Access_level = 1 Then
        Me.Hide()
        AdminMainMenu.Show()
    ElseIf Access_Level = 0 Then
        Me.Hide()
        MainMenu.Show()
    Else
        MessageBox.Show("Sorry, No match")
    End If
    TextBox1.Clear()
    TextBox2.Clear()
End Sub

将 retVal 更改为对象。

从 objCmd.ExecuteScalar() 中移除 CInt

没有检查并返回 -1 Else CInt(RetVal)

于 2020-04-04T19:00:41.243 回答