3

谁能注意到以下功能可能有什么问题:

public string Login(string username, string password)
    {
        string result = "";
        string select = "SELECT user_id FROM [user] WHERE username = @username AND password = @password";
        SqlConnection conn = new SqlConnection(connectionString);
        SqlCommand cmd = new SqlCommand(select, conn);
        cmd.Parameters.AddWithValue("username", username);
        cmd.Parameters.AddWithValue("password", password);
        int userID = 0;
        try
        {
            conn.Open();
            userID = (int)cmd.ExecuteScalar();
            if(userID > 0)
            {
                result = addSession(userID);
            }
        }
        catch(Exception ex)
        {
            string sDummy = ex.ToString();
        }
        return result;
    }

不知道为什么行`userID = (int)cmd.ExecuteScalar(); 抛出异常。

谢谢

4

6 回答 6

6

表中很可能没有包含该用户/密码的行。ExecuteScalar的文档说,如果结果集为空,它会返回 null,并且您不能将 null 转换为 int。

于 2009-03-24T03:02:52.127 回答
2

您应该考虑修改这段代码:

try
{
    conn.Open();
    userID = (int)cmd.ExecuteScalar();
    if(userID > 0)
    {
        result = addSession(userID);
    }
 }
 catch(Exception ex)
 {
    string sDummy = ex.ToString();

 }
 finally // add this to ensure the connection is closed!
 {
     if (conn != null)
       conn.Close();
 }
于 2009-03-24T02:52:57.127 回答
1

如果在数据库中找不到提供的凭据,标量是否可能为空?

于 2009-03-24T03:00:16.797 回答
0

不确定,但您可能需要“@”作为参数名称:

...AddWithValue("@username", username);
于 2009-03-24T02:53:28.873 回答
0

我在使用 SqlCE 时遇到了同样的问题。我找到的解决方案(在我开始正确输入密码之后... >.> )是首先将 ExecuteScalar 结果作为对象收集,然后再进行转换。从字面上看,使用

Object o = cmd.ExecuteScalar(); 
int id = Convert.ToInt32(o); 

代替

int id = (int) cmd.ExecuteScalar(); 

是工作和崩溃之间的区别。我不知道为什么会这样……

于 2012-11-26T07:48:13.370 回答
0

我没有看到任何 hashbytes 函数,但它是这样的:

如果您hashbytes在后端 SQL 服务器上使用函数,则将密码输入转换为二进制数组。Hashbytes 返回 varbinary。因此,如果您传递空终止符,则哈希将不一样。就像在 SQLhashbytes('SHA2_512,'stuff')中一样,就像散列's','t',直到'f'。最后没有'\0'。但是,如果您在 sqlcommand 对象中参数化为字符串,它将在末尾添加 '\0' 并且 SQL 将计算该零。因此,如果您将使用Encoding类转换为二进制数组,则参数将只是没有空终止符的字符串。我遇到了类似的问题,我以这种方式解决了使用问题,addwithvalue并将其值作为二进制文件。

但是,您知道 executescalar 返回一个对象。如果查询返回零行,则该对象将为 NULL,并且您不能将 NULL 对象强制转换或转换为任何对象。所以在 if 语句中说“如果返回对象 == null 那么你没有经过身份验证。否则......”

于 2016-08-29T11:12:38.103 回答