2009-03-24 4 views
3

Можно ли заметить, что может быть не так с помощью следующей функции:SQLCommand.ExecuteScalar() - почему он генерирует исключение System.NullReferenceException?

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

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

Благодаря

+0

Вы должны опубликовать полное исключение, включая любое InnerException. –

+0

Чтобы избежать другой проблемы, приложите поле «пароль» в квадратных скобках, так как это также зарезервированное слово. – HardCode

ответ

4

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

+1

Хорошая практика при вызове ExecuteScalar заключается в том, чтобы убедиться, что запрос возвращает результат. Запрос может быть изменен на: ** SELECT ISNULL (MAX (user_id), - 1) FROM [USER] ... ** –

1

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

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

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

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

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

0

У меня была эта же проблема с SqlCE. Решение, которое я нашел, (ПОСЛЕ того, как я начал вводить пароль CORRECTLY ...>.>), Должен был сначала собрать результат ExecuteScalar как объект и преобразовать второй. Litterally, используя

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

вместо

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

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

0

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

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

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

Смежные вопросы