如何在ajax方法中进行filterContext.Result调用操作时重定向页面?

时间:2016-04-26 16:26:35

标签: javascript c# asp.net-mvc asp.net-ajax actionfilterattribute

我遇到了一个我不知道如何修复的问题。

我的问题的上下文是基于在会话变量丢失时将用户重定向到Login的需要。

我们正在做的是对预览执行操作的控制器操作进行修饰,验证名为[“SesionesPorUsuarios”]的会话变量,其中不同于null

这样的事情:

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

然后像这样:

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

我们的登录操作是:

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

我们遇到了问题,当在$ .post()

等ajax方法中调用该操作时

post方法获取操作“Login”返回的所有视图,但它不会将用户重定向到Login页面,post方法获取操作“Login”返回的所有html,并将其视为一个JSON对象。

enter image description here

任何人都知道我们如何解决这个问题,或者我们可以根据需要应用什么工作

...谢谢

3 个答案:

答案 0 :(得分:4)

您必须检查它是否是ajax请求并将URL发送为json,并在客户端检查该param是否通过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" }
                               });
 }

并注册ajaxError事件并在该检查中查找值并重定向:

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

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

        });

现在在任何ajax调用上如果session为null,用户将被重定向到登录操作。

您也可以返回一个对象而不是字符串@Shyju在帖子中演示,我使用字符串来保持简单:)

答案 1 :(得分:1)

您可以更新操作过滤器以检查请求是否来自ajax调用。如果是,则返回带有要重定向到的登录URL的json响应。您可以通过检查请求中的"X-Requested-With"标头来确定它是否是ajax调用。对于ajax请求,值为"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
  }
}

现在,在$.post方法的回调中,检查此数据并执行任何操作。

编辑:根据评论

如果您有许多地方正在进行ajax通话,则可以在全局ajaxComplete事件中执行此操作。

$(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()检查X-Requested-With标头值。如果您使用角度js的$http服务来进行这些调用,则会使用此特定标头will not be available。在这种情况下,您需要专门将其添加到您的电话中。

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

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

答案 2 :(得分:0)

我的朋友们,你们已经给了我们解决问题的答案,非常感谢你们。

我们用来解决问题的方法是:

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

并在全球js上查看:

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

问题解决了,真的非常感谢。