2

Je suis venu avec un problème que je ne sais pas comment résoudre.Comment rediriger la page lorsque l'appel à l'action filterContext.Result a été effectué dans la méthode ajax?

Le contexte de mon problème est basé sur le besoin de rediriger l'utilisateur vers Login lorsqu'une variable de session est perdue.

Ce que nous faisons est une décoration sur les actions du contrôleur que prévisualisations pour exécuter l'action, valident cette variable de session intitulée [ « SesionesPorUsuarios »] où il est différent de null

Quelque chose comme ceci:

[HttpPost] 
    [IndicadorUltimaAccionDelSistema()] 
    public JsonResult ConsulteLosProductos(string elAliasDelTipoDeProducto) 
    { 
     //stuffs... 
    } 

Et puis comme ceci:

public class IndicadorUltimaAccionDelSistema : ActionFilterAttribute 
{ 

     /stuffs... 
     public override void OnActionExecuting(ActionExecutingContext filterContext) 
     { 
      if (HttpContext.Current.Session["SesionesPorUsuarios"] != null) 
      {    
       /stuffs... 
      } 
      else 
      { 
       /stuffs... 
       filterContext.Result = new RedirectToRouteResult(
            new RouteValueDictionary 
            { 
             { "action", "Login" }, 
             { "controller", "Login" } 
            }); 
      } 
     } 
} 

notre action de connexion est:

public ActionResult Login() 
    { 
     return View(); 
    } 

Nous avons eu le problème, lorsque l'action est appelée dans une méthode ajax comme .post de $()

La méthode post reçoit toute la vue retournée par l'action « Connexion », mais il ne pas les redirections l'utilisateur à la page de connexion, la méthode post obtient tout le html retourné par l'action "Login" et il le traite comme un objet JSON.

enter image description here

Tout le monde sait comment nous pouvons résoudre ce problème, ou ce workarround pouvons-nous demander la nécessité

Merci ...

Répondre

1

Vous pouvez mettre à jour votre filtre d'action pour vérifier si la demande vient d'un appel ajax ou pas. Si oui, renvoyez une réponse json avec l'URL de connexion à rediriger. Vous pouvez déterminer s'il s'agit d'un appel ajax ou non en vérifiant l'en-tête "X-Requested-With" dans la requête. Pour toute demande de paiement ajax est la valeur sera "XmlHttpRequest"

public override void OnActionExecuting(ActionExecutingContext context) 
{  
    if(YourCodeToCheckWhetherUserIsAuthenticatedHere()==false) 
    { 
     var url = new UrlHelper(context.Controller.ControllerContext.RequestContext) 
                .Action("Login", "Account"); 
     if (context.HttpContext.Request.IsAjaxRequest()) 
     { 
     context.Result = new JsonResult { Data = new { LoginUrl = url} }; 
     } 
     //to do : Non ajax request. keep your existing code 
    } 
} 

maintenant dans votre dos à l'appel de la méthode $.post, vérifier ces données et faire tout ce que vous voulez.

EDIT: D'après le commentaire

Si vous avez beaucoup d'endroits que vous faites appel ajax, vous pouvez faire cette vérification en cas ajaxComplete global.

$(function(){ 
    $(document).ajaxComplete(function(a,xhr,c) { 
     if (xhr.status === 401) { 
      var d = $.parseJSON(xhr.responseText); 
      //alert("login failed"); // Let's redirect 
      window.location.href = d.LoginUrl; 
     } 
    }); 
}); 

Request.IsAjaxMethod() vérifie la valeur d'en-tête. X-Requested-With Si vous utilisez le service $http angulaire de js pour effectuer ces appels, cet en-tête spécifique will not be available. Dans ce cas, vous devez l'ajouter spécifiquement à vos appels.

var app= angular.module('yourApp', []); 

app.config(['$httpProvider', function ($httpProvider) { 
    $httpProvider.defaults.headers.common["X-Requested-With"] = 'XMLHttpRequest'; 
}]); 
+0

Merci pour votre commentaire et prendre le temps de répondre à ma question. Le problème avec cette solution, est que nous devons changer tout le code sur chaque méthode post appel d'action. S'il n'y a pas une autre solution, nous aply quelque chose comme ça, même si cela signifie que les régressions possibles. Merci encore pour votre temps. – mmadrigal

3

Vous devez vérifier si elle est une demande de paiement ajax et envoyer url JSON et contrôle côté client si ce param est là redirigent du côté client via js:

if (filterContext.HttpContext.Request.IsAjaxRequest()) 
{ 
    filterContext.HttpContext.Response.StatusCode = 403; 
    filterContext.Result = new JsonResult { Data = "LogOut"}; 
} 
else 
{ 
    filterContext.Result = new RedirectToRouteResult(
           new RouteValueDictionary 
           { 
            { "action", "Login" }, 
            { "controller", "Login" } 
           }); 
} 

et le registre ajaxError événement et que l'enregistrement de la valeur et de rediriger:

$(document).ajaxError(function(e, xhr, opts) { 

      if (xhr.status == 403 && xhr.responseText.indexOf("LogOut") != -1) { 
       window.location.href = "@Url.Action("Login", "Account")"; 
      } 

     }); 

maintenant sur un appel ajax si la session est null utilisateur sera redirigé sur l'action ouvrir une session.

Vous pouvez également retourner un objet au lieu de chaîne comme @Shyju a démontré dans le poste, j'ai utilisé la chaîne pour le garder simple :)

+0

Merci pour votre commentaire et prenez le temps de répondre à ma question. Le problème avec cette solution, est que nous devons changer tout le code sur chaque méthode post appel d'action. S'il n'y a pas une autre solution, nous aply quelque chose comme ça, même si cela signifie que les régressions possibles. Merci encore pour votre temps. – mmadrigal

+0

vous pouvez le rendre plus facile en ne la demande, permettez-moi de modifier le message –

+0

@mmadrigaln voir mon post mise à jour, elle pourra être utile –

0

Mes amis, vous nous avez donné les réponses à notre problème, merci beaucoup .

La façon dont nous utilisons pour résoudre le problème était:

if (filterContext.HttpContext.Request.IsAjaxRequest()) 
       { 
        filterContext.HttpContext.Response.StatusCode = 403; 
        filterContext.Result = new JsonResult { Data = "LogOut" }; 
       } 
       else { 
        filterContext.Result = new RedirectToRouteResult(
             new RouteValueDictionary 
             { 
             { "action", "Login" }, 
             { "controller", "Login" } 
             }); 
       } 

Et vérifiez sur les js mondiaux comme celui-ci:

$(function() { 
      $(document).ajaxComplete(function (a, xhr, c) { 
       if (xhr.status == 403 && xhr.responseText.indexOf("LogOut") != -1) { 
        window.location.href = "@Url.Action("Login", "Login")"; 
       } 
      }); 
     }); 

Le problème a été résolu, vraiment vraiment merci.

+0

Vous ne devriez pas poster votre propre réponse, vous devez plutôt marquer comme répondre l'une des réponses données –