Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/331.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 必须声明标量变量"@用户名";_C#_Sql_Asp.net_Database_Authentication - Fatal编程技术网

C# 必须声明标量变量"@用户名";

C# 必须声明标量变量"@用户名";,c#,sql,asp.net,database,authentication,C#,Sql,Asp.net,Database,Authentication,我不断地犯一个我不明白的错误 必须声明标量变量“@varname” 我的目标是创建一个登录页面,该页面使用两个文本框和一个按钮,根据存储在SQL数据库中的信息检查用户是否退出 这就是我认为问题的根源: private bool DBConnection(string userName, string password) { SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["

我不断地犯一个我不明白的错误

必须声明标量变量“@varname”

我的目标是创建一个登录页面,该页面使用两个文本框和一个按钮,根据存储在SQL数据库中的信息检查用户是否退出

这就是我认为问题的根源:

private bool DBConnection(string userName, string password)
{
    SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString);
    
    //string cmdString = ("SELECT UserName, Password FROM Users WHERE UserName ='" + userName +
    //                    "'AND Password ='" + password + "'");         //REMOVED AS THIS IS PRONE TO SQL INJECTIONS
    
    string cmdString = ("SELECT * FROM Users WHERE UserName = @uname AND Password = @pw");
    
    SqlCommand cmd = new SqlCommand(cmdString, conn);
    
    cmd.Parameters.Add("uname", SqlDbType.VarChar).Value = userName;
    cmd.Parameters.Add("pw", SqlDbType.VarChar).Value = password;

    DataSet loginCredentials = new DataSet();
    SqlDataAdapter dataAdapter;

    try
    {
        if (conn.State.Equals(ConnectionState.Closed))
        {
            conn.Open();

            dataAdapter = new SqlDataAdapter(cmdString, conn);
            dataAdapter.Fill(loginCredentials);

            conn.Close();

            if (loginCredentials != null)
            {
                if (loginCredentials.Tables[0].Rows.Count > 0)
                {
                    return true;
                }
                else
                {
                    lblMessage.Text = "Incorrect Username or Password";
                    lblMessage.Visible = true;
                }
            }   
        }
    }
    catch (Exception err)
    {
        lblMessage.Text = err.Message.ToString() + " Error connecting to the Database // " + cmd.Parameters.Count;
        lblMessage.Visible = true;
        return false;
    }

    return false;
}
特别是
dataAdapter.Fill(loginCredentials)

注释掉的语句可以成功地使用正确的用户名和密码登录用户,但据我所知,它是不安全的,因为它容易受到SQL注入的攻击,这就是我尝试参数化SQL语句的原因

错误截图如下:


请注意uname前面的@。

您需要将
cmd
传递给
SqlDataAdapter
构造函数,而不是
cmdString
conn
对象。

除了下面描述的所有错误(或在这里;)。。您正在向数据适配器传递命令行和连接,但您正在填充未使用的命令上的参数……)因此您有几个错误…

您应该将sqlcommand传递给dataAdapter,因为在您的情况下,sqlcommand(cmd)包含的信息不仅仅是commandtext和connectionstring。您的代码可能如下所示:

private bool DBConnection(string userName, string password)
{
 SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString);

//string cmdString = ("SELECT UserName, Password FROM Users WHERE UserName ='" + userName +
//                    "'AND Password ='" + password + "'");         //REMOVED AS THIS IS PRONE TO SQL INJECTIONS

string cmdString = ("SELECT * FROM Users WHERE UserName = @uname AND Password = @pw");

SqlCommand cmd = new SqlCommand(cmdString, conn);

cmd.Parameters.Add("uname", SqlDbType.VarChar).Value = userName;
cmd.Parameters.Add("pw", SqlDbType.VarChar).Value = password;

DataSet loginCredentials = new DataSet();
SqlDataAdapter dataAdapter;

try
{
    if (conn.State.Equals(ConnectionState.Closed))
    {
        conn.Open();

        dataAdapter = new SqlDataAdapter(cmd);
        dataAdapter.Fill(loginCredentials);

        conn.Close();

        if (loginCredentials != null)
        {
            if (loginCredentials.Tables[0].Rows.Count > 0)
            {
                return true;
            }
            else
            {
                lblMessage.Text = "Incorrect Username or Password";
                lblMessage.Visible = true;
            }
        }   
    }
}
catch (Exception err)
{
    lblMessage.Text = err.Message.ToString() + " Error connecting to the Database // " + cmd.Parameters.Count;
    lblMessage.Visible = true;
    return false;
}

return false;
}

最重要的是,首先检查是否为特定变量分配了某个值,即

cmd.parameter.add(@YOUR_VARIABLE, sqlDbtype.TYPE).value = ValueYouwantToGIveToThatVariable;

@参数中的字符是可选的。而不是
dataAdapter=new-SqlDataAdapter(cmdString,conn)使用
dataAdapter.SelectCommand=cmd我也遇到了同样的问题,经过大量的研究,我偶然发现了你的答案,它是有效的。你知道为什么在这个特定的场景中调用新的SqlDataAccess(cmdString,conn)不起作用吗?这与这里的问题没有直接关系,但我在OleDbDataAdapter和这里的搜索结果中遇到了类似的问题。对于OleDb,SQL文本中的参数应使用?字符作为位置占位符。如果SQL文本在SQL文本中有@paramname这样的参数,并且使用SQL Server,您可能会得到相同的“必须声明标量变量”错误,请将代码替换为:“对于试图理解此问题的人来说非常没有帮助,特别是当代码块太大时。@Crattle:如果到目前为止还不能得到答案,你可以发布一个问题。@Mubarek-谢谢,我已经解决了我的问题。这个问题是一个搜索结果,查找此错误消息,我为通过此途径的其他人留下了我的评论。我没有留下答案,因为这与行动计划的情况无关。
cmd.parameter.add(@YOUR_VARIABLE, sqlDbtype.TYPE).value = ValueYouwantToGIveToThatVariable;