Home > Software engineering >  Asp.net redirect to action failed with status code 500
Asp.net redirect to action failed with status code 500

Time:01-28

currently I'm working on the login function of a simple asp.net application. The login function uses SweetAlert as the form collector and send ajax to the backend to login the user. The login function somehow works, because I debugged it and it goes to the Success case. The problem seems to happen on the code under Success, where it requires to redirect to action with the given url. Here is my code:

Frontend

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

BackEnd

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

And here is the response:

Request URL: https://localhost:44354/Account/Login
Request Method: POST
Status Code: 302 
Remote Address: [::1]:44354
Referrer Policy: strict-origin-when-cross-origin

I think the problem happened on return RedirectToAction(parsedUrl[1], parsedUrl[0]); in backend Login(). I tried to set the parameter directly to the returnUrl but still not work. The webpage does not redirect to anywhere. Instead, it goes to the error block in the front end ajax and popup the internal error message.

Any suggestion will be appreciated.

--------------------------Edit--------------------------------

I found the reason of status 302. It is because I specify in ajax that the response type is Json, but backend return with RedirectToAction(). But still I need some suggestions. I remove dataType: "json", and it responses will status 500. How should I redirect the user after login in this case?

CodePudding user response:

It looks like you're using a single controller action to handle both JSON/API-calls and regular HTML page requests:

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

Regular page requests and API-calls behave differently.

Generally speaking:

  • A regular page request expects a HTML response and will follow a redirect automatically.
  • A API-call expects a JSON response and doesn't follow a redirect.

If you want to have redirect behavior from your API-call, you'd have to do do this manually:

  1. Inspecting the status code (equals 302)
  2. Extracting the url from the Location response header
  3. Redirect the user to this url using JavaScript: window.location.href=url
  •  Tags:  
  • Related