使用MVC行为过滤器来捕捉Ajax请求的重定向和返回JsonResult [英] Using an MVC Action Filter to catch redirects in Ajax requests and return a 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屋!