使用MVC行为过滤器来捕捉Ajax请求的重定向和返回JsonResult [英] Using an MVC Action Filter to catch redirects in Ajax requests and return a JsonResult

查看:1038
本文介绍了使用MVC行为过滤器来捕捉Ajax请求的重定向和返回JsonResult的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我的ASP.NET MVC 3应用程序,我可以在Ajax和非Ajax请求调用一些操作方法。动作方法可以返回一个RedirectResult,我想在浏览器中加载的目标URL - 即使是Ajax请求

我目前的解决方案是操作方法调用IsAjaxRequest本身。如果是假,它返回一个RedirectResult。如果为true,它返回一个包含目标URL一个JsonResult,我在浏览器脚本阅读本和一套相应window.location的

我希望能简化房间的操作方法,并在过滤处理这个问题。我的问题是,目标URL(filterContext.HttpContext.Response.RedirectLocation)是在比OnResultExecuted其他过滤器的事件处理程序无效,并在该处理程序设置filterContext.Result(和改变response.Status code)不会成功在响应发出的JSON

如果我用其他的处理程序,如OnActionExecuted之一,我可以改变发出JSON响应,但不能得到目标URL的搁置。

2步过程中不工作,要么 - 如果我改变结果在OnActionExecuted一个JsonResult时,RedirectLocation是空的OnResultExecuted

任何人都可以重现这个问题,或者推荐一个更好的解决方案?谢谢你。

PS这里是OnResultExecuted的code:

  IF((filterContext.Result是RedirectToRouteResult ||
     filterContext.Result是RedirectResult)及&放大器;
     filterContext.HttpContext.Request.IsAjaxRequest())
{
    字符串的URL = filterContext.HttpContext.Response.RedirectLocation;    filterContext.HttpContext.Response.Status code =(INT)的HTTPStatus code.OK;    filterContext.HttpContext.Response.RedirectLocation =;    filterContext.Result =新JsonResult
    {
        数据=新的{重定向URL =},
        ContentEncoding = System.Text.Encoding.UTF8,
        的ContentType =应用/ JSON
        JsonRequestBehavior = JsonRequestBehavior.AllowGet
    };
}


解决方案

下面是你如何能进行一个例子:

 公共覆盖无效OnActionExecuted(ActionExecutedContext filterContext)
{
    base.OnActionExecuted(filterContext);    如果(filterContext.HttpContext.Request.IsAjaxRequest())
    {
        字符串的URL =/;
        VAR redirectResult = filterContext.Result为RedirectResult;
        如果(filterContext.Result是RedirectResult)
        {
            //这是一个RedirectResult =>我们需要计算链接
            VAR的结果= filterContext.Result为RedirectResult;
            URL = UrlHelper.GenerateContentUrl(result.Url,filterContext.HttpContext);
        }
        否则,如果(filterContext.Result是RedirectToRouteResult)
        {
            //这是一个RedirectToRouteResult =>我们需要计算
            //目标网址
            VAR的结果= filterContext.Result为RedirectToRouteResult;
            URL = UrlHelper.GenerateUrl(result.RouteName,NULL,NULL,result.RouteValues​​,RouteTable.Routes,filterContext.RequestContext,FALSE);
        }
        filterContext.Result =新JsonResult
        {
            数据=新的{重定向URL =},
            JsonRequestBehavior = JsonRequestBehavior.AllowGet
        };
    }
    其他
    {
        // TODO:这不是一个AJAX请求=>做任何你在做
    }
}

In my ASP.NET MVC 3 application, I have some action methods that can be invoked with Ajax and non-Ajax requests. The action methods may return a RedirectResult and I want the target URL to be loaded in the browser - even for Ajax requests.

My current solution is for the action method to call IsAjaxRequest itself. If false, it returns a RedirectResult. If true, it returns a JsonResult containing the target URL, and I have script in the browser to read this and set window.location accordingly.

I was hoping to declutter the action methods and handle this in a filter. My problem is that the target URL (filterContext.HttpContext.Response.RedirectLocation) is null in the filter event handlers other than OnResultExecuted, and setting filterContext.Result in that handler (and changing response.StatusCode) doesn't succeed in issuing JSON in the response.

If I use one of the other handlers, such as OnActionExecuted, I can change the response to issue JSON, but cannot get hold of the target URL.

A 2-step process does not work either - if I change the result to a JsonResult in OnActionExecuted, the RedirectLocation is null in OnResultExecuted.

Can anyone recreate this problem or recommend a better solution? Thanks.

PS here is the code from OnResultExecuted:

if ((filterContext.Result is RedirectToRouteResult || 
     filterContext.Result is RedirectResult) && 
     filterContext.HttpContext.Request.IsAjaxRequest())
{
    string url = filterContext.HttpContext.Response.RedirectLocation;

    filterContext.HttpContext.Response.StatusCode = (int)HttpStatusCode.OK;

    filterContext.HttpContext.Response.RedirectLocation = "";

    filterContext.Result = new JsonResult
    {
        Data = new { Redirect = url },
        ContentEncoding = System.Text.Encoding.UTF8,
        ContentType = "application/json",
        JsonRequestBehavior = JsonRequestBehavior.AllowGet
    };
}

解决方案

Here's an example of how you could proceed:

public override void OnActionExecuted(ActionExecutedContext filterContext)
{
    base.OnActionExecuted(filterContext);

    if (filterContext.HttpContext.Request.IsAjaxRequest())
    {
        string url = "/";
        var redirectResult = filterContext.Result as RedirectResult;
        if (filterContext.Result is RedirectResult)
        {
            // It was a RedirectResult => we need to calculate the url
            var result = filterContext.Result as RedirectResult;
            url = UrlHelper.GenerateContentUrl(result.Url, filterContext.HttpContext);
        }
        else if (filterContext.Result is RedirectToRouteResult)
        {
            // It was a RedirectToRouteResult => we need to calculate
            // the target url
            var result = filterContext.Result as RedirectToRouteResult;
            url = UrlHelper.GenerateUrl(result.RouteName, null, null, result.RouteValues, RouteTable.Routes, filterContext.RequestContext, false);
        }
        filterContext.Result = new JsonResult
        {
            Data = new { Redirect = url },
            JsonRequestBehavior = JsonRequestBehavior.AllowGet
        };
    }
    else
    {
        // TODO: It is not an AJAX request => do whatever you were doing
    }
}

这篇关于使用MVC行为过滤器来捕捉Ajax请求的重定向和返回JsonResult的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆