C# SqlDataReader = null?

3
            String sqlCheckPass = 
"Select * from Login where Username like @Username and Password like @Password";
        SqlCommand SqlCom = new SqlCommand(sqlCheckPass, myConnection);
        SqlCom.Parameters.Add(new SqlParameter("@Username", sUserName));
        SqlCom.Parameters.Add(new SqlParameter("@Password", sPassword));

        myConnection.Open();
        SqlDataReader myreader;
        myreader = SqlCom.ExecuteReader();
        int id = -1;

ErrorBox.InnerHtml = "Username:" + sUserName + ":" + sPassword + ":<br/>";
while (myreader.HasRows)
{
    id = (int)myreader["id"];
    String sUser = (String)myreader["Username"];
    String sPass = (String)myreader["Password"];
    ErrorBox.InnerHtml += "UserId is <b>" + id + "</b> " + sUser + ":" + sPass + ":<br >";
    Session["LoginID"] = id;
    Server.Transfer(ReturnPage);

}
if (id == -1)
{
    ErrorBox.InnerHtml = "Incorrect Password";
}
myConnection.Close();
catch (Exception err)
{
    ErrorBox.InnerHtml = "Error Getting  Option ID" + err.Message;
}

我在 myreader = SqlCom.ExecuteReader(); 处设置了断点,但它一直返回 null,HasRows = False,但它确实有行。因此,它一直将我的登录验证为不正确,因为 id = -1。

需要帮助吗?


发布代码应该是生成“SqlCom”的过程。 - Robin Day
1
其次...如果myreader为空,则“HasRows”不能为false。 - Robin Day
不要将您的密码以明文形式存储在数据库中,如果有人获得该表的访问权限会发生什么?最好将它们作为哈希值存储。 - Martin Milan
另外,你在创建命令对象时应该明确指定参数的类型... - Martin Milan
3个回答

4

您没有将读取器连接到SQL连接/命令吗?


SqlConnection myConnection = new SqlConnection(myConnectionString);
SqlCommand myCommand = new SqlCommand(mySelectQuery, myConnection);
myConnection.Open();
SqlDataReader myReader = myCommand.ExecuteReader(CommandBehavior.CloseConnection);
while(myReader.Read()) 
{
   Console.WriteLine(myReader.GetString(0));
}
myReader.Close();

+1 - 显然它没有被初始化,因此为NULL。其他值只是默认值。 - ChrisBD
@Chris - 什么没有初始化? - tom
您的连接字符串设置正确吗?有没有在try/catch或类似的块中抛出异常? - Bryan Denny
是的,绝对正确,因为它可以将数据库中的名称获取到一个下拉列表中,我已经暂时设置好了。 - tom
而且@David提出了一个很好的建议,这也可能是您查询格式的问题。 - Bryan Denny

1

问题可能是你的查询中使用了SqlParameter的LIKE。尝试

String sqlCheckPass =  
"Select * from Login where Username like '%' + @Username + '%' and Password like '%' + @Password + '%'"; 

2
顺便问一下,你为什么使用LIKE而不是“=”? - David
很酷。然而,使用LIKE %%进行身份验证是危险的。你应该使用“=”。 - David
不要使用LIKE来检查用户名和密码。 - ZippyV
使用“=”而不是“like”可以获得+1。我也很好奇...在添加通配符之前,两个参数的值是什么,以至于没有返回任何数据... - Ricardo Sanchez

1
Bryan Denny的回答是正确的,不过我会将所有代码都放在使用语句中,如下所示:
using (SqlConnection dataConnection = new SqlConnection(connectionString))
{
    using (SqlCommand SqlCom = dataConnection.CreateCommand())
    {
        SqlCom.CommandText = "Select * from Login where Username like @Username and Password like @Password";
        SqlCom.Parameters.Add(new SqlParameter("@Username", sUserName)); 
        SqlCom.Parameters.Add(new SqlParameter("@Password", sPassword)); 

        dataConnection.Open();
        SqlDataReader myreader; 
        myreader = SqlCom.ExecuteReader(); 
        dataConnection.Close();
    }
}

我没有将你的所有代码添加到这个片段中,我想你已经明白了。

另外,你可以尝试修改选择语句以返回记录数,因为这是你所需要的全部内容,一个数字:

SELECT COUNT(*) FROM Login WHERE Username like @Username AND Password like @Password

祝你好运!


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接