SQLCommand.ExecuteScalar () - почему он вызывает исключение System.NullReferenceException? - PullRequest
3 голосов
/ 24 марта 2009

Может ли кто-нибудь заметить, что может быть не так со следующей функцией:

public string Login(string username, string password)
    {
        string result = "";
        string select = "SELECT user_id FROM [user] WHERE username = @username AND password = @password";
        SqlConnection conn = new SqlConnection(connectionString);
        SqlCommand cmd = new SqlCommand(select, conn);
        cmd.Parameters.AddWithValue("username", username);
        cmd.Parameters.AddWithValue("password", password);
        int userID = 0;
        try
        {
            conn.Open();
            userID = (int)cmd.ExecuteScalar();
            if(userID > 0)
            {
                result = addSession(userID);
            }
        }
        catch(Exception ex)
        {
            string sDummy = ex.ToString();
        }
        return result;
    }

Не знаю, почему строка `userID = (int) cmd.ExecuteScalar (); выдает исключение.

Спасибо

Ответы [ 6 ]

5 голосов
/ 24 марта 2009

Скорее всего, в таблице нет строки с этим пользователем / паролем. Документы для ExecuteScalar говорят, что он возвращает ноль, если набор результатов пуст, и вы не можете привести ноль к int.

1 голос
/ 24 марта 2009

Возможно ли, что скаляр равен нулю, если предоставленные учетные данные не найдены в базе данных?

1 голос
/ 24 марта 2009

Вы должны рассмотреть возможность изменения этого сегмента кода:

try
{
    conn.Open();
    userID = (int)cmd.ExecuteScalar();
    if(userID > 0)
    {
        result = addSession(userID);
    }
 }
 catch(Exception ex)
 {
    string sDummy = ex.ToString();

 }
 finally // add this to ensure the connection is closed!
 {
     if (conn != null)
       conn.Close();
 }
0 голосов
/ 29 августа 2016

Я не вижу функции хешбайта, но здесь она идет:

Преобразование ввода пароля в двоичный массив, если вы используете функцию hashbytes на внутреннем SQL-сервере. Hashbytes возвращает varbinary. Таким образом, если вы передадите нулевой терминатор, хеш не будет таким же. как в SQL hashbytes('SHA2_512,'stuff') похоже на хеширование 's', 't' до 'f'. В конце нет \ 0. Но если вы параметризируете как строку в объекте sqlcommand, это добавит '\ 0' в конце, и SQL вычислит этот ноль. Поэтому, если вы преобразуете класс Encoding в двоичный массив, параметром будет просто строка без нулевого терминатора. У меня возникла похожая проблема, и я решил таким образом использовать addwithvalue и его значение в двоичном виде.

Но вы знаете, что executetescalar возвращает объект. Если запрос возвращает ноль строк, объект будет иметь значение NULL, и вы не сможете ни преобразовать, ни преобразовать объект NULL ни во что. Таким образом, в операторе if говорится «если returningobject == null, то вы не авторизованы. Else ....»

0 голосов
/ 26 ноября 2012

У меня была такая же проблема при работе с SqlCE. Решение, которое я нашел (ПОСЛЕ того, как я начал вводить свой пароль ПРАВИЛЬНО ...>.>), Заключалось в том, чтобы сначала собрать результат ExecuteScalar как объект, а затем преобразовать второй. Буквально, используя

Object o = cmd.ExecuteScalar(); 
int id = Convert.ToInt32(o); 

вместо

int id = (int) cmd.ExecuteScalar(); 

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

0 голосов
/ 24 марта 2009

Не уверен, но вам может потребоваться "@" для имен параметров:

...AddWithValue("@username", username);
...