Как исправить нулевое значение этой StoredProcedure в C #? - PullRequest
1 голос
/ 11 мая 2019

Я сделал хранимую процедуру для пользователей, чтобы войти в приложение, но независимо от того, что я пытался и смотрел много руководств по хранимым процедурам, мне не удалось вернуть значения.

Я также пытался с выходными параметрамиполучить значения обратно, а также попытался с 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();

1 Ответ

0 голосов
/ 11 мая 2019

Вы записали пароль пользователя в виде простого текста. С другой стороны, пароль хранится в базе данных как varbinary. Вы не можете сравнить nvarchar с varbinary. Вы можете выбрать хеширование пароля пользователя на стороне клиента. Это также правильный подход. В этом случае вы должны изменить свой SP, чтобы получать varbinary в качестве параметра, и ваша логика будет в порядке. Это означает "И [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; }


    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...