我为用户创建了一个存储过程以登录应用程序,但是无论我尝试了什么,并且观看了许多存储过程指南,但都没有设法取回值。
我也尝试使用输出参数来获取值,也尝试使用DatarReader但未分配值。出于某种原因,调试会忽略对象值。
在SQL Server中,我尝试存储的某些DECLARE
方法似乎可以正常工作,但在C#中我没有任何值。
这是第一个存储过程:
ALTER PROCEDURE spAddUser
@pLogin NVARCHAR(50),
@pPassword NVARCHAR(50),
@pRole nvarchar(20)
AS
BEGIN
INSERT INTO [UsersDetails] (LoginName, PasswordHash, UserRole)
VALUES(@pLogin, HASHBYTES('SHA2_512', @pPassword), @pRole)
END;
CREATE PROCEDURE [dbo].[spLogin]
@uname NVARCHAR(50),
@pass VARCHAR(50)
AS
BEGIN
SELECT LoginName,[PasswordHash],UserRole
FROM UsersDetails
WHERE LoginName=@uname AND [PasswordHash]=@pass
END;
GO
Console.WriteLine("Enter Username and Password to Login");
string userLogin = Console.ReadLine();
string passwordLogin = Console.ReadLine();
SqlCommand cmdLogin = new SqlCommand();
cmdLogin.Connection = sqlcon;
cmdLogin.CommandType = CommandType.StoredProcedure;
cmdLogin.CommandText = "spLogin";
cmdLogin.Parameters.Add(new SqlParameter("@uname", SqlDbType.NVarChar)).Value = userLogin;
cmdLogin.Parameters.Add(new SqlParameter("@pass", SqlDbType.NVarChar)).Value = passwordLogin;
cmdLogin.Parameters["@uname"].Direction = ParameterDirection.ReturnValue;
SqlDataReader loginReader = cmdLogin.ExecuteReader();
while (loginReader.Read())
{
User user = new User
{
ID = loginReader.GetInt32(0),
LoginName = loginReader.GetString(1),
PasswordHash = loginReader.GetString(2)
};
Console.Write(user);
}
loginReader.Close();
答案 0 :(得分:0)
您以纯文本形式捕获了用户密码。另一方面,密码以varbinary的形式存储在数据库中。您无法将nvarchar与varbinary进行比较。您可以选择在客户端对用户密码进行哈希处理。这也是一种有效的方法。在那种情况下,您应该更改您的SP以接收varbinary作为参数,并且您的逻辑会很好。意思是“ AND [PasswrodHash] = @ pass。
尝试插入下面的代码段所示的记录,然后更改存储过程。注意,用户名为“ darko”,密码为“ MyTestPas”
CREATE TABLE UsersDetails
(id INTEGER IDENTITY PRIMARY KEY CLUSTERED ,
LoginName NVARCHAR(50) NOT NULL,
PasswordHash VARBINARY(4000) NOT NULL,
UserRole NVARCHAR(50) NOT NULL
);
INSERT INTO UsersDetails
(loginname,
passwordhash,
userrole
)
SELECT 'darko',
HASHBYTES('SHA2_512', 'MyTestPas'),
'admin';
--Check the result
SELECT *
FROM UsersDetails;
CREATE PROCEDURE [dbo].[spLogin] @uname NVARCHAR(50),
@pass VARCHAR(50)
AS
BEGIN
SELECT ID,
LoginName,
[PasswordHash],
UserRole
FROM UsersDetails
WHERE LoginName = @uname
AND [PasswordHash] = HASHBYTES('SHA2_512', @pass);
END;
GO
使用以下代码段更改.NET代码。注意,为简单起见,我用常量代替读取用户名和密码。第二个注意事项是,您必须更改连接字符串。
using System;
using System.Data;
using System.Data.SqlClient;
namespace ConsoleApp21
{
class Program
{
static void Main()
{
// these are read from the command line as the plain text
const string userLogin = "darko";
const string passwordLogin = "MyTestPas";
// Change to match your connection string
var sqlcon = new SqlConnection("Integrated Security = true; Initial Catalog = your database; Server = your server");
sqlcon.Open();
var cmdLogin = new SqlCommand
{
Connection = sqlcon, CommandType = CommandType.StoredProcedure, CommandText = "spLogin"
};
cmdLogin.Parameters.Add(new SqlParameter("@uname", SqlDbType.NVarChar)).Value = userLogin;
cmdLogin.Parameters.Add(new SqlParameter("@pass", SqlDbType.NVarChar)).Value = passwordLogin;
var loginReader = cmdLogin.ExecuteReader();
while (loginReader.Read())
{
var user = new User
{
LoginName = (string)loginReader["LoginName"],
UserRole = (string)loginReader["UserRole"]
};
Console.Write($"{user.LoginName}({user.UserRole})");
}
loginReader.Close();
Console.ReadLine();
}
}
public class User
{
public string UserRole { get; set; }
public string LoginName { get; set; }
public Byte PasswordHash { get; set; }
public int Id { get; set; }
}
}