Asp.net 重定向到操作失败,状态代码为 500
Asp.net redirect to action failed with status code 500
目前我正在开发一个简单的 asp.net 应用程序的登录功能。登录功能使用 SweetAlert 作为表单收集器,并发送 ajax 到后端以登录用户。登录功能以某种方式工作,因为我调试了它并且它进入了成功案例。问题似乎发生在 Success 下的代码上,它需要重定向到给定 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
我认为问题发生在后端 Login()
的 return RedirectToAction(parsedUrl[1], parsedUrl[0]);
上。我试图将参数直接设置为 returnUrl 但仍然不起作用。该网页不会重定向到任何地方。相反,它转到前端的错误块 ajax 并弹出内部错误消息。
如有任何建议,我们将不胜感激。
------------------------编辑---------------- --------------
我找到了状态302的原因。这是因为我在ajax中指定响应类型是Json,但是后端return是RedirectToAction()
。但我仍然需要一些建议。我删除了 dataType: "json"
,它的响应状态为 500。在这种情况下,我应该如何在登录后重定向用户?
看起来您正在使用单个控制器操作来处理 JSON/API-calls 和常规 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-calls 行为不同。
一般来说:
- 常规页面请求需要 HTML 响应并将自动遵循重定向。
- A API-call 需要 JSON 响应并且不遵循重定向。
如果您想从 API-call 中获得重定向行为,您必须手动执行此操作:
- 检查状态码(等于
302
)
- 从
Location
响应中提取 url header
- 使用 JavaScript 将用户重定向到此 url:
window.location.href=url
目前我正在开发一个简单的 asp.net 应用程序的登录功能。登录功能使用 SweetAlert 作为表单收集器,并发送 ajax 到后端以登录用户。登录功能以某种方式工作,因为我调试了它并且它进入了成功案例。问题似乎发生在 Success 下的代码上,它需要重定向到给定 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
我认为问题发生在后端 Login()
的 return RedirectToAction(parsedUrl[1], parsedUrl[0]);
上。我试图将参数直接设置为 returnUrl 但仍然不起作用。该网页不会重定向到任何地方。相反,它转到前端的错误块 ajax 并弹出内部错误消息。
如有任何建议,我们将不胜感激。
------------------------编辑---------------- --------------
我找到了状态302的原因。这是因为我在ajax中指定响应类型是Json,但是后端return是RedirectToAction()
。但我仍然需要一些建议。我删除了 dataType: "json"
,它的响应状态为 500。在这种情况下,我应该如何在登录后重定向用户?
看起来您正在使用单个控制器操作来处理 JSON/API-calls 和常规 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-calls 行为不同。
一般来说:
- 常规页面请求需要 HTML 响应并将自动遵循重定向。
- A API-call 需要 JSON 响应并且不遵循重定向。
如果您想从 API-call 中获得重定向行为,您必须手动执行此操作:
- 检查状态码(等于
302
) - 从
Location
响应中提取 url header - 使用 JavaScript 将用户重定向到此 url:
window.location.href=url