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?

alex
  • 6,818
  • 9
  • 52
  • 103
s.k.paul
  • 7,099
  • 28
  • 93
  • 168

3 Answers3

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;
  }
 });
Ramunas
  • 3,853
  • 1
  • 30
  • 31
  • okey :D , how can i achieve redirection to a view with model from js/server side with this same approach ? – J_P Jan 06 '16 at 06:52
2

This help me.

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

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

Community
  • 1
  • 1
BJ Patel
  • 6,148
  • 11
  • 47
  • 81
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.

Shahin Dohan
  • 6,149
  • 3
  • 41
  • 58