c# #sql-server #asp.net-mvc #asp.net-web-api
#c# #sql-сервер #asp.net-mvc #asp.net-web-api
Вопрос:
Я пытаюсь войти в систему, но я не понимаю, почему контроллер выдает ошибку при ExecuteScalar
Ссылка на объект не установлена для экземпляра объекта
Если кто-нибудь может мне помочь в этом, пожалуйста, дайте мне знать, и любые предложения по улучшению этого будут оценены
Вот мой код ajax:
$('#login').click(function (ev) {
ev.preventDefault();
FieldValidation();
var data = new Object();
data.UserName = $('#username').val();
data.UPassword = $('#userpass').val();
if (data.UserName amp;amp; data.UPassword) {
$.ajax({
url: 'http://localhost:1089/api/Employee/IfExist',
type: "POST",
dataType: 'json',
contentType: "application/json",
data: JSON.stringify(data),
beforeSend: function () {
$("#dvRoomsLoader").show();
},
complete: function () {
$("#dvRoomsLoader").hide();
},
success: function (data) {
if (data.Role = "Admin")
window.location = "../Admin/Index";
if (data.Role = "Employee")
window.location = "../Employee/Index";
},
error: function (ex) {
alert('Error' ex.responseXML);
alert('Error' ex.responseText);
alert('Error' ex.responseJSON);
alert('Error' ex.readyState);
alert('Error' ex.statusText);
}
});
}
return false;
});
Это то, что я записал в своей хранимой процедуре:
SELECT *
FROM Employee
WHERE UserName = @UserName AND pass = @pass
UPDATE Employee
SET IsActive = 1
WHERE UserName = @UserName AND pass = @pass
Это метод, который я создал в контроллере для вызова при попадании ajax:
[HttpPost]
public bool IfExist(Employee emp)
{
var con = DB.getDatabaseConnection();
SqlCommand com = new SqlCommand("sp_CheckUserIfExists", con);
com.CommandType = CommandType.StoredProcedure;
#region If the User Exist then what to do Code Block
com.Parameters.AddWithValue("@UserName", emp.UserName);
com.Parameters.AddWithValue("@pass", emp.UPassword);
// com.ExecuteScalar();
int UserExist = (int)com.ExecuteScalar();
#endregion
if (UserExist > 0)
{
return true;
}
else
{
return false;
}
}
Комментарии:
1. Проверьте параметры:
emp
,emp.UserName
иemp.UPassword
. Один из нихnull
.2. Если пользователь с этим паролем не существует , то хранимая процедура возвращает
NULL
— который вы затем пытаетесь преобразовать(int)
в свой вызовExecuteScalar
— без проверкиNULL
!3. Примечание: вы не должны использовать
sp_
префикс для своих хранимых процедур. Microsoft зарезервировала этот префикс для собственного использования (см. Раздел Именование хранимых процедур ) , и вы рискуете столкнуться с конфликтом имен когда-нибудь в будущем. Это также плохо сказывается на производительности вашей хранимой процедуры . Лучше просто избегатьsp_
и использовать что-то еще в качестве префикса — или вообще без префикса!4. Я также надеюсь , что вы не храните пароли в виде простого текста в своей базе данных; вышеприведенное выглядит так, как будто вы вполне можете быть.
5. Вы должны солить и хэшировать свои пароли, @SyedMuhammadAousajaAli . Поиск по этой методологии приведет к множеству статей, руководств и документации.
Ответ №1:
ExecuteScalar обычно используется для запросов Select и возвращает первый столбец select . Поэтому измените select на это
SELECT Count(*)
FROM Employee
WHERE UserName = @UserName AND pass = @pass
....
но лучше использовать только второе утверждение вашего sp
UPDATE Employee
SET IsActive = 1
WHERE UserName = @UserName AND pass = @pass
и он вернет количество затронутых строк, если вы используете executenonquery
int rows= (int)com.ExecuteNonQuery();
bool UserExist= rows >0;