2

Ich kam mit einem Problem, das ich nicht beheben kann.Wie wird die Seite umgeleitet, wenn der Aufruf von filterContext.Result zur Aktion in der Ajax-Methode durchgeführt wurde?

Der Kontext meines Problems basiert auf der Notwendigkeit, den Benutzer zur Anmeldung umzuleiten, wenn eine Sitzungsvariable verloren geht.

Was wir tun, ist eine Dekoration über den Controller-Aktionen, die Vorschauen die Aktion auszuführen, validieren, dass die Session-Variable namens [ „SesionesPorUsuarios“], wo verschiedene

So etwas wie dies auf null:

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

Und dann wie folgt aus:

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

unsere Anmeldung Aktion ist:

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

Wir haben das Problem, wenn die Aktion in einer Ajax-Methode wie $ .post()

genannt wird

Die post-Methode erhält die alle Blick durch die Aktion „Login“ zurück, aber es nicht tun Umleitungen Wenn der Benutzer die Anmeldeseite aufruft, erhält die Post-Methode den gesamten von der Aktion "Login" zurückgegebenen HTML-Code und behandelt ihn wie ein JSON-Objekt.

enter image description here

Jeder weiß, wie wir dieses Problem beheben können, oder welche workarround können wir für die Notwendigkeit

Dank gilt ...

Antwort

1

Sie können Ihre Aktion Filter aktualisieren, ob die Anforderung überprüfen kommt von einem Ajax-Anruf oder nicht. Wenn ja, geben Sie eine json-Antwort mit der Login-URL zurück, an die weitergeleitet werden soll. Sie können feststellen, ob es sich um einen Ajax-Anruf handelt oder nicht, indem Sie den Header "X-Requested-With" in der Anfrage überprüfen. Für Ajax-Request ist der Wert "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 
    } 
} 

Jetzt in Ihrer $.post Methode Aufruf wird zurück, diese Daten überprüfen und tun, was Sie wollen.

EDIT: Basierend auf den Kommentar

Wenn Sie viele Orte haben Sie Ajax-Aufruf machen Sie diese Überprüfung in der globalen ajaxComplete Ereignis tun.

$(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() prüft den X-Requested-With Header-Wert. Wenn Sie den Dienst $http von angular js verwenden, um diese Aufrufe durchzuführen, geben Sie diesen spezifischen Header will not be available ein. In diesem Fall müssen Sie das speziell zu Ihren Anrufen hinzufügen.

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

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

Vielen Dank für Ihren Kommentar und nehmen Sie sich Zeit, um meine Frage zu beantworten. Das Problem mit dieser Lösung ist, dass wir den gesamten Code bei jedem Post-Methoden-Aktionsaufruf ändern sollten. Wenn es keine andere Lösung gibt, werden wir so etwas anwenden, obwohl es mögliche Regressionen bedeutet. Nochmals vielen Dank für Ihre Zeit. – mmadrigal

3

Sie müssen überprüfen, ob es sich um eine Ajax-Anforderung und senden url als json ist und auf Client-Seite zu überprüfen, ob die param dort von Client-Seite über js Umleitung ist:

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

und registrieren ajaxError Ereignis und in dieser Prüfung auf Wert und umleiten:

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

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

     }); 

nun auf jedem ajax-Aufruf, wenn Sitzung null Benutzer erhalten umgeleitet Aktion anmelden.

Sie können auch ein Objekt statt String zurück als @Shyju in der Post gezeigt, verwendet i-String es einfach :)

+0

Vielen Dank für Ihren Kommentar und nehmen Sie sich Zeit, um meine Frage zu beantworten. Das Problem mit dieser Lösung ist, dass wir den gesamten Code bei jedem Post-Methoden-Aktionsaufruf ändern sollten. Wenn es keine andere Lösung gibt, werden wir so etwas anwenden, obwohl es mögliche Regressionen bedeutet. Nochmals vielen Dank für Ihre Zeit. – mmadrigal

+0

Sie können es einfacher machen, indem Sie die Anfrage fehlschlagen, lassen Sie mich den Beitrag bearbeiten –

+0

@mmadrigaln siehe meinen aktualisierten Beitrag, hoffe es hilft –

0

Meine Freunde zu halten, haben Sie uns gegeben haben, die Antworten für unser Problem, danke so viel .

Die Art, wie wir das Problem zu beheben war:

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

Und es auf den globalen js wie folgt überprüfen:

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

Das Problem wurde gelöst, wirklich, wirklich danke.

+0

Sie sollten nicht Ihre eigene Antwort posten, stattdessen müssen Sie eine der Antworten als Antwort markieren –