C# sqlCommand.Parameters not select right



我有一个应测试登录的代码。当我从字面上执行时,它可以正常工作,返回一排(预计)。当我在sqlcommand上使用参数时,我没有任何行。

它有效(用户名和密码的文字值):

string strConn = 'string connection';
SqlConnection conn = new SqlConnection(strConn);
SqlCommand sqlCommand = new SqlCommand();
sqlCommand.Connection = conn;
sqlCommand.Parameters.Clear();
sqlCommand.CommandText = @"select *
                           from
                              Usuario
                           where
                              Username = 'test' and
                              Password = CONVERT(VARCHAR(32), ashBytes('MD5', 'test'), 2)";
conn.Open();
SqlDataReader ret = sqlCommand.ExecuteReader();

但它不起作用(用户名和密码的参数值):

string strConn = 'string connection';
SqlConnection conn = new SqlConnection(strConn);
SqlCommand sqlCommand = new SqlCommand();
sqlCommand.Connection = conn;
sqlCommand.Parameters.Clear();
sqlCommand.CommandText = @"select *
                           from
                              Usuario
                           where
                              Username = @login and
                              Password = CONVERT(VARCHAR(32), ashBytes('MD5', @pass), 2)";
SqlParameter user = new SqlParameter("@login", SqlDbType.NVarChar, 50) { Value = "test" };
SqlParameter pass = new SqlParameter("@pass", SqlDbType.NVarChar, 50) { Value = "test" };
List<SqlParameter> list = new List<SqlParameter>();
list.Add(user);
list.Add(pass);
sqlCommand.Parameters.AddRange(list.ToArray<SqlParameter>());
conn.Open();
SqlDataReader ret = sqlCommand.ExecuteReader();

我没有Sintax错误或类似的错误。第二个代码只是不返回行。我尝试使用sqlcommand.parameters.addwithvalue,但我也没有成功。

'test'N'test'将它们转换为哈希时不是同一回事。一个是ASCII,另一个是Unicode。如果它们都是ASCII,则在您的参数中使用SqlDbType.VarChar(不是SqlDbType.NVarChar)。


sql

中说明的差异
DECLARE @passUnicode Nvarchar(100) = N'test'
DECLARE @passAscii varchar(100) = 'test'
SELECT CONVERT(VARCHAR(32), HashBytes('MD5', @passAscii), 2) AS [Md5OfAscii]
     , CONVERT(VARCHAR(32), HashBytes('MD5', @passUnicode), 2) AS [Md5OfUnicode]

结果

098F6BCD4621D373CADE4E832627B4F6, C8059E2EC7419F590E79D7F1B774BFE6

侧注

密码哈希

我建议不要将密码存储为MD5,MD5根本不安全。那里有很多替代方案,例如pbkdf2bcryptscrypt,可以命名一些更普遍接受的安全密码散列算法。

C#结构

使用ado.net(或与此相关的任何资源)时,应包装连接,数据标准,适配器等,以在using块中实现IDisposable。这将确保即使在连接的情况下,也将始终释放外部资源。

string connectionString = "";
using (var connection = new SqlConnection(connectionString))
{
    using (var command = new SqlCommand
    {
        CommandText = @"select * from Usuario where Username = @login and Password = CONVERT(VARCHAR(32), HASHBYTES('MD5', @pass), 2)",
        CommandType = CommandType.Text,
        Connection = connection
    })
    {
        command.Parameters.Add(new SqlParameter("login", SqlDbType.VarChar, 50) { Value = "test" });
        command.Parameters.Add(new SqlParameter("pass", SqlDbType.VarChar, 50) { Value = "test" });
        connection.Open();
        using (var dataReader = command.ExecuteReader())
        {
            // do some stuff
        }
    }
}

最新更新