ASP.NET SqlConnection错误:“ConnectionString属性尚未初始化”

时间:2011-01-15 07:39:15

标签: asp.net sql-server vb.net

这个T-SQL查询出了什么问题:

 Protected Sub Button1_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles Button1.Click
        Dim SQLData As New System.Data.SqlClient.SqlConnection("Data Source=.\SQLEXPRESS;AttachDbFilename=|DataDirectory|\Database.mdf;Integrated Security=True;User Instance=True")
        Dim cmdSelect As New System.Data.SqlClient.SqlCommand("SELECT COUNT(*) FROM Table1 WHERE Name ='" + TextBox1.Text + "'", SQLData)
        SQLData.Open()
        If cmdSelect.ExecuteScalar > 0 Then
            Label1.Text = "You have already voted this service"
            Return
        End If
        Dim con As New SqlConnection
        Dim cmd As New SqlCommand
        con.Open()
        cmd.Connection = con
        cmd.CommandText = "INSERT INTO Tabel1 (Name) VALUES('" & Trim(Label1.Text) & "')"
        cmd.ExecuteNonQuery()
        Label1.Text = "Thank You !"
        SQLData.Close()
    End Sub

3 个答案:

答案 0 :(得分:1)

您的问题是您正在打开连接(SQLData),忽略它,然后尝试打开新连接(con)而不给它连接字符串。而不是:

     Dim con As New SqlConnection
     Dim cmd As New SqlCommand
     con.Open()
     cmd.Connection = con 

你应该:

     Dim cmd As New SqlCommand
     cmd.Connection = SQLData

此外,在SQL中插入字符串值是非常糟糕的做法。

答案 1 :(得分:0)

我发现有一些错误。首先,(除了SQL注入漏洞之外)是您输入Table1一次,而Tabel1则是另一次。虽然这可能是你想要的,但我对此表示怀疑。接下来,您将创建第二个连接。这似乎不需要。使用现有的SQLData对象而不是con。您还可以使用以下内容减少从cmd(包括)声明到ExecuteNonQuery调用(不包括)的行:

Dim cmd As New SqlCommand("INSERT INTO Tabel1 (Name) VALUES('" & Trim(Label1.Text) & "')", SQLData)

现在回到SQL注入漏洞。如果有人的名字是“詹姆斯·奥布莱恩”(或其他带有撇号的东西)怎么办?

答案 2 :(得分:0)

我建议采用这样的方法:

Protected Function Button1_Click(sender As Object, e As System.EventArgs)
    ' define and create your one single SqlConnection and protect it by using a "using()....." block
    Using _connection As New SqlConnection("Data Source=.\SQLEXPRESS;AttachDbFilename=|DataDirectory|\Database.mdf;Integrated Security=True;User Instance=True")
        ' define and craete your SqlCommand to count your occurences and make it a proper, parametrized query
        Using cmdSelect As New SqlCommand("SELECT COUNT(*) FROM dbo.Table1 WHERE Name = @Name", _connection)
            ' add the parameter to your SqlCommand, define the datatype and length
            cmdSelect.Parameters.Add("@Name", SqlDbType.VarChar, 100)

            ' set the value for that parameter
            cmdSelect.Parameters("@Name").Value = TextBox1.Text.Trim()

            ' open connection, execute query, set return value
            _connection.Open()
            If cmdSelect.ExecuteScalar() > 0 Then
                            Label1.Text = "You have already voted this service"
                Return 
            End If
        End Using

        ' define second query to insert data reusing the existing connection
        Using cmdInsert As New SqlCommand("INSERT INTO dbo.Table1(Name) VALUES(@Name)", _connection)
            ' add the parameter to your SqlCommand, define the datatype and length
            cmdInsert.Parameters.Add("@Name", SqlDbType.VarChar, 100)

            ' set the value for that parameter
            cmdInsert.Parameters("@Name").Value = Label1.Text.Trim()

            cmdInsert.ExecuteNonQuery()
        End Using

        _connection.Close()
    End Using

    Label1.Text = "Thank You !"
End Function

要考虑的要点:

  • 您有一个 SqlConnection - 这对两个查询都足够好,可以重复使用它!

  • 始终SqlConnectionSqlCommand等一次性对象放入Using.....块以保护它们并确保它们得到妥善处理

  • 始终使用参数化查询 - 在任何情况下执行 NOT 只是将SQL语句连接在一起 - 这是一个巨大的巨大安全性洞,邀请SQL注入攻击 - 只是不要这样做 - 永远!

  • 如果可以的话,我会尝试将您的UI元素与代码分开 - 尝试将此代码放入一个单独的方法,该方法将从调用者接收字符串值,并返回一个结果字符串在UI上设置(Label1.Text=)。混合查询数据库并同时设置UI的代码很混乱,导致意大利面条代码 - 尝试将这些内容分开

  • 将您的连接字符串放入web.config <connectionStrings>部分并从那里读取 - 在整个代码中没有连接字符串作为字符串文字!