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 根本不安全。有很多替代方案,例如 pbkdf2
、bcrypt
和 scrypt
,仅举几例更普遍接受的安全密码哈希算法。
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
}
}
}
我有一个代码可以测试登录。 当我按字面执行时,它会工作,返回一行(这是预期的)。当我在 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 根本不安全。有很多替代方案,例如 pbkdf2
、bcrypt
和 scrypt
,仅举几例更普遍接受的安全密码哈希算法。
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
}
}
}