使用SQL的C#简单用户名/密码,用户始终无效

时间:2012-11-09 23:32:16

标签: c# sql login

我正在尝试使用SQL创建一个简单的用户名/密码登录,它始终显示为无效。我可以得到一些反馈吗?

 SqlConnection cn;
        cn = new SqlConnection();
        cn.ConnectionString = "Data source=(local); Initial Catalog=INT422Assignment1; Integrated Security=SSPI;";
        cn.Open();
        SqlCommand cmd;
        cmd = new SqlCommand();
        cmd.Connection = cn;
        cmd.CommandText = "SELECT username, pwd FROM myLogin WHERE userNameTB = @username AND passWordTB = @pwd";

        SqlParameter param;
        param = new SqlParameter("@username", SqlDbType.VarChar);
        param.Direction = ParameterDirection.Input;
        param.Value = userNameTB;
        cmd.Parameters.Add(param);

        param = new SqlParameter("@pwd", SqlDbType.VarChar);
        param.Direction = ParameterDirection.Input;
        param.Value = passWordTB;
        cmd.Parameters.Add(param);

        try
        {
            cmd.ExecuteNonQuery();
            cn.Close();
            MessageBox.Show("Login"); 
        }
        catch (Exception ex)
        {
            MessageBox.Show("Invalid");
        }           
    }

它运行,我在命令文本行之后放入一个断路器,所以我看到它接收来自文本字段的输入,但不知何故它不会将它与数据库中的用户名和密码进行比较。

我感谢你的帮助。

干杯,

ESSI

5 个答案:

答案 0 :(得分:2)

如果它始终显示为无效,则表明您的查询正在抛出异常,因为仅当捕获到异常时才会显示“无效”框。该例外的细节是什么?

如果您阅读SqlCommand.ExecuteNonQuery()上的文档,您会注意到在您的情况下,它没有任何用处:

  

对于UPDATE,INSERT和DELETE语句,返回值是受影响的行数   通过命令。当插入或更新的表上存在触发器时,返回   value包括插入或更新操作所影响的行数   受触发器或触发器影响的行数。对于所有其他类型的陈述,   返回值为-1。如果发生回滚,则返回值也为-1。

所以ExecuteNonQuery()不是正确的方法。我怀疑你的异常被抛出与你执行一个select语句有关,因为使用了ExecuteNonQuery()而生成了一个尚未处理的结果集。

顺便说一下,我会注意到,对控制流程序逻辑使用异常被认为是不好的做法。例外情况是...... 异常条件,而不是普通的程序逻辑。此外,当捕获异常时,应该尽可能具体。否则,正如您所发现的那样,您会捕获不应该被捕获的异常,这会导致其他问题。)

我会做这样的事情:

static bool IsAuthenticated( string uid , string pwd )
{
    if ( string.IsNullOrWhiteSpace(uid) ) throw new ArgumentNullException("uid") ;
    if ( string.IsNullOrWhiteSpace(pwd) ) throw new ArgumentNullException("pwd") ;

    bool authenticated ;

    using ( SqlConnection cn = new SqlConnection("Data source=(local); Initial Catalog=INT422Assignment1; Integrated Security=SSPI;") )
    using ( SqlCommand    cmd = cn.CreateCommand() )
    {

        cmd.CommandType = CommandType.Text ;
        cmd.CommandText = @"
SELECT authenticated = count(*)
FROM myLogin
WHERE userNameTB = @username
AND passWordTB = @pwd"
        ;

        cmd.Parameters.AddWithValue( "@username" , uid ) ;
        cmd.Parameters.AddWithValue( "@pwd"      , pwd ) ;

        cn.Open() ;

        authenticated = ((int)cmd.ExecuteScalar()) > 0 ? true : false ;
    cmd.ExecuteNonQuery();

        cn.Close() ;

    }

    return authenticated ;

}

答案 1 :(得分:0)

使用ExecuteScalar()执行查询不会返回任何内容。或者使用SqlDataAdapter并填写DataTable并查看DataTable中是否有任何行,或者使用ExecuteScalar()来获取从数据库返回的第一个项目。您需要从数据库返回的数据。

另一方面,我会使用已经内置了用户登录/输出功能的ASP.NET成员资格。我不会构建自己的登录注销网页。

答案 2 :(得分:0)

try
        {
            cmd.ExecuteNonQuery();  //this is for inserting or updating db
            cn.Close();
            MessageBox.Show("Login"); 
        }
        catch (Exception ex)
        {
            MessageBox.Show("Invalid");
        }     

使用SqlDataReader

尝试此操作
try{
     SqlDataReader dr = cmd.ExecuteReader()
     While dr.Read() {

      string password = dr("pwd").ToString();
      string username = dr("username").ToString();
      }  
     }

编辑:

 try{
     SqlDataReader dr = cmd.ExecuteReader();
     If dr.HasRows() {
         //Here is your code for good login
      }
     }

答案 3 :(得分:0)

没有结果的SQL查询不会引发异常。你需要得到结果并检查它们是否为空:if(res.MoveNext())。

答案 4 :(得分:-2)

我认为您不需要此代码中的@符号。

 SqlParameter param;
    param = new SqlParameter("username", SqlDbType.VarChar);
    param.Direction = ParameterDirection.Input;
    param.Value = userNameTB;
    cmd.Parameters.Add(param);

我认为参数名称应该只是pwd的用户名相同