web-dev-qa-db-fra.com

Redirection côté serveur après un appel jquery ajax dans asp.net mvc 4

J'envoie les informations de connexion d'un appel jQuery AJAX à un contrôleur MVC 4:

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

Si la connexion aboutit, je souhaite rediriger un utilisateur côté serveur vers la page appropriée en fonction du type d'utilisateur. Si la connexion échoue, une chaîne est renvoyée à l'utilisateur:

    [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.
        }
    }

Mais il y a des problèmes:

  1. Si cette méthode retourne 'ActionResult', j'obtiens l'erreur not all code paths return a value.

  2. Si j'utilise 'void', je ne peux rien retourner.

  3. Même si j'utilise 'void' sans retour, je ne parviens pas à rediriger vers un autre contrôleur ou une vue en raison de la nature asynchrone des appels jQuery AJAX.

Existe-t-il des techniques pour gérer de tels scénarios?

22
s.k.paul

return retourne généralement de la méthode sans exécuter aucune autre instruction, donc la partie else n'est pas nécessaire. De cette façon, vous vous débarrasserez d'un problème n ° 1.

Quant à la redirection, pourquoi ne pas renvoyer une sorte de 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")});
}

Et puis en 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;
  }
 });
48
Ramunas

Cela m'aide.

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

Réf. link Comment obtenir une réponse ASP.NET MVC Ajax à rediriger vers une nouvelle page ...

2
BJ Patel

Je devais le faire, mais aucune des solutions que j'ai trouvées ne répondait vraiment à mes exigences extrêmes d'analyse d'erreur JavaScript que je devais éviter pour rediriger le client vers la page de connexion.

Ce que j'ai fait est d'envoyer une simple réponse "NOAUTH" à partir de mon attribut d'autorisation personnalisé, puis d'intercepter la réponse Ajax avant que les gestionnaires d'événements ne soient touchés et de rediriger l'utilisateur en définissant window.location.

Du côté serveur:

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

Ensuite côté client:

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

Je ne recommanderais pas cette approche cependant. Si vous devez le faire, je suggère au moins de placer plutôt la valeur "NOAUTH" dans l'en-tête de la réponse http, puis de lire la valeur dans un gestionnaire complet JQuery complet.

Du côté serveur:

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

Côté client:

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

Notez que l'utilisation de dataFilter est le moyen seulement d'intercepter les demandes ajax avant qu'un autre de vos gestionnaires d'événements ne soit touché.

0
Shahin Dohan