24

I am sending login information from a jQuery AJAX call to an MVC 4 controller:

   $.post(url, data, function (response) {
      if (response=='InvalidLogin') {
          //show invalid login
      }
      else if (response == 'Error') {
          //show error
      }
      else {
          //redirecting to main page from here for the time being.
          window.location.replace("http://localhost:1378/Dashboard/Index");
      }
   });

If the login is successful, I want to redirect a user from the server-side to the appropriate page on the basis of user type. If the login fails, a string is sent back to user:

    [HttpPost]
    public ActionResult Index(LoginModel loginData)
    {
        if (login fails)
        {
            return Json("InvalidLogin", JsonRequestBehavior.AllowGet);
        }
        else
        {
             // I want to redirect to another controller, view, or action depending
             // on user type.
        }
    }

But there are problems:

  1. If this method returns 'ActionResult', then I'm getting the error not all code paths return a value.

  2. If I use 'void', I cannot return anything.

  3. Even if I use 'void' with no return, I am failing to redirect to other controller or view due to asynchronous nature of jQuery AJAX calls.

Are there any techniques to handle such scenarios?

5
  • Have you considered trying to return something - anything, in the else of your ActionResult? Commented Nov 5, 2013 at 17:40
  • Return "Success" in your else. Commented Nov 5, 2013 at 17:50
  • @Jasen, you did not read carefully the problem. Commented Nov 5, 2013 at 17:57
  • How so? Return something from your controller and catching the response in javascript solves problem 1 & 2. The answer you accepted is essentially the same thing. Commented Nov 5, 2013 at 18:23
  • @Jasen, please show us if you have something better than the accepted answer. Commented Nov 5, 2013 at 18:43

3 Answers 3

51

return usually returns from method without executing any further statements in it so else part is not needed. This way you will get rid of a problem #1.

As for redirecting why not return some kind of redirect command:

[HttpPost]
public ActionResult Index(LoginModel loginData)
{
    if (login fails)
    {
        return Json(new {result = "InvalidLogin"}, JsonRequestBehavior.AllowGet);
    }
    return Json(new {result = "Redirect", url = Url.Action("MyAction", "MyController")});
}

And then in javascript:

$.post(url, data, function (response) {
  if (response.result == 'InvalidLogin') {
      //show invalid login
  }
  else if (response.result == 'Error') {
      //show error
  }
  else if (response.result == 'Redirect'){
      //redirecting to main page from here for the time being.
      window.location = response.url;
  }
 });
Sign up to request clarification or add additional context in comments.

1 Comment

okey :D , how can i achieve redirection to a view with model from js/server side with this same approach ?
2

This help me.

return JavaScript("window.location = '/'");

Ref. link How to get an ASP.NET MVC Ajax response to redirect to new page...

Comments

0

I had to do this but none of the solutions I found really satisfied my extreme requirements of JavaScript parsing errors that I had to avoid in order to redirect the client to the login page.

What I did was to send a simple "NOAUTH" string response from my custom Authorization attribute, then intercept the Ajax response before any event handlers are hit, and redirect the user by setting window.location.

Server side:

protected override void HandleUnauthorizedRequest(AuthorizationContext context)
{
    if (context.RequestContext.HttpContext.Request.IsAjaxRequest())
    {
        var result = new ContentResult {Content = "NOAUTH"};
        context.Result = result;
        return;
    }
}

Then on the client side:

$.ajaxSetup({
    dataFilter: function (data, type) {
        if (data !== "" && data === "NOAUTH") {
            window.location = '/';
        }
        return data;
    }
});

I would not recommend this approach though. If you have to do this, then I would at-least suggest instead putting the "NOAUTH" value inside the http response header, then read the value in a global JQuery complete handler.

Server side:

HttpContext.Current.Response.AddHeader("NOAUTH", "1");

Client-side:

$.ajaxSetup({
    complete: function (jqXHR, textStatus) {
        if (jqXHR.getResponseHeader("NOAUTH") === '1')
            window.location = '/';
    }
});

Note that using dataFilter is the only way to intercept ajax requests before any other of your event handlers are hit.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.