#c# #html #asp.net #asp.net-mvc-4 #redirect
Вопрос:
в настоящее время я работаю над простой функцией входа в систему. asp.net применение. Функция входа в систему использует SweetAlert в качестве сборщика форм и отправляет ajax на серверную часть, чтобы войти в систему пользователя. Функция входа каким-то образом работает, потому что я отладил ее, и это приведет к успеху. Проблема, похоже, возникает с кодом при успешном выполнении, где требуется перенаправление на действие с заданным URL-адресом. Вот мой код:
Внешний интерфейс
function login() {
Swal.fire({
// some sweet alert stuff
}).then((result) => {
if (!result.isConfirmed) return;
var data = {
__RequestVerificationToken: gettoken(),
email: result.value.username,
password: result.value.password,
returnUrl:"@ViewContext.Controller.ValueProvider.GetValue("controller").RawValue.ToString()/@ViewContext.Controller.ValueProvider.GetValue("action").RawValue.ToString()"
}
/* console.log(data)*/
$.ajax({
type: "POST",
url: '/Account/Login',
data: data,
contentType: "application/x-www-form-urlencoded; charset=utf-8",
dataType: "json",
success: function (response) {
console.log(response)
if (!response.success) onFail("Your username or password is incorrect.", login);
},
error: function (response) {
console.log(response)
onFail("Internal error, please try again", login)
}
})
})
}
бэкэнд
// POST: /Account/Login
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Login(LoginViewModel model, string returnUrl)
{
if (!ModelState.IsValid)
{
return View(model);
}
var result = await SignInManager.PasswordSignInAsync(model.Email, model.Password, model.RememberMe, shouldLockout: false);
switch (result)
{
case SignInStatus.Success:
string[] parsedUrl = returnUrl.Split('/');
return RedirectToAction(parsedUrl[1], parsedUrl[0]);
case SignInStatus.LockedOut:
return View("Lockout");
case SignInStatus.RequiresVerification:
return RedirectToAction("SendCode", new { ReturnUrl = returnUrl, RememberMe = model.RememberMe });
case SignInStatus.Failure:
return Json(new { success = false, html = "", message = "Internal Error" });
default:
ModelState.AddModelError("", "Invalid login attempt.");
return View(model);
}
}
И вот вам ответ:
Request URL: https://localhost:44354/Account/Login
Request Method: POST
Status Code: 302
Remote Address: [::1]:44354
Referrer Policy: strict-origin-when-cross-origin
Я думаю, что проблема произошла return RedirectToAction(parsedUrl[1], parsedUrl[0]);
в бэкэнде Login()
. Я попытался установить параметр непосредственно в returnUrl, но все равно не получилось. Веб — страница никуда не перенаправляется. Вместо этого он переходит к блоку ошибок в интерфейсе ajax и выводит внутреннее сообщение об ошибке.
Любое предложение будет оценено по достоинству.
—————————Редактировать———————————
Я нашел причину статуса 302. Это потому, что я указываю в ajax, что тип ответа-Json, но серверная часть возвращается с RedirectToAction()
. Но все же мне нужны некоторые предложения. Я удаляю dataType: "json"
, и он получит статус 500. Как я должен перенаправить пользователя после входа в систему в этом случае?
Ответ №1:
Похоже, вы используете одно действие контроллера для обработки как вызовов JSON/API, так и обычных запросов HTML-страниц:
case SignInStatus.LockedOut:
return View("Lockout");
case SignInStatus.RequiresVerification:
return RedirectToAction("SendCode", new { ReturnUrl = returnUrl, RememberMe = model.RememberMe });
case SignInStatus.Failure:
return Json(new { success = false, html = "", message = "Internal Error" });
Обычные запросы на страницы и вызовы API ведут себя по-разному.
Вообще говоря:
- Обычный запрос на страницу ожидает ответа в формате HTML и автоматически последует за перенаправлением.
- Вызов API ожидает ответа JSON и не следует за перенаправлением.
Если вы хотите, чтобы поведение перенаправления из вашего API-вызова было перенаправлено, вам придется сделать это вручную:
- Проверка кода состояния (равно
302
) - Извлечение URL — адреса из заголовка
Location
ответа - Перенаправьте пользователя на этот URL-адрес с помощью JavaScript:
window.location.href=url