C# sqlCommand.Parameters 不 Select 正确

C# sqlCommand.Parameters don't Select properly

我有一个代码可以测试登录。 当我按字面执行时,它会工作,返回一行(这是预期的)。当我在 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();

我没有语法错误或类似错误。第二个代码只是没有 returns 行。 我试过使用 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(或与此相关的任何资源)时,您应该包装实现 IDisposable 的连接、数据读取器、适配器等在 using 块中。这将确保始终释放外部资源,即使在连接的情况下也是如此。

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
        }
    }
}