【问题标题】:Using an MVC Action Filter to catch redirects in Ajax requests and return a JsonResult使用 MVC 操作过滤器捕获 Ajax 请求中的重定向并返回 JsonResult
【发布时间】:2011-02-11 16:23:00
【问题描述】:

在我的 ASP.NET MVC 3 应用程序中,我有一些可以通过 Ajax 和非 Ajax 请求调用的操作方法。操作方法可能会返回 RedirectResult,我希望将目标 URL 加载到浏览器中 - 即使是 Ajax 请求。

我当前的解决方案是让 action 方法调用 IsAjaxRequest 本身。如果为 false,则返回 RedirectResult。如果为真,它会返回一个包含目标 URL 的 JsonResult,我在浏览器中有脚本来读取它并相应地设置 window.location。

我希望整理动作方法并在过滤器中处理它。我的问题是目标 URL(filterContext.HttpContext.Response.RedirectLocation)在除 OnResultExecuted 之外的过滤器事件处理程序中为空,并且在该处理程序中设置 filterContext.Result(并更改 response.StatusCode)无法成功发出 JSON回应。

如果我使用其他处理程序之一,例如 OnActionExecuted,我可以更改响应以发出 JSON,但无法获取目标 URL。

两步过程也不起作用 - 如果我在 OnActionExecuted 中将结果更改为 JsonResult,则 OnResultExecuted 中的 RedirectLocation 为空。

谁能重现这个问题或推荐更好的解决方案?谢谢。

PS 这里是来自 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
    };
}

【问题讨论】:

  • 嗨@DGreen 能否请您显示用于在Ajax 请求的情况下重定向到其他位置的脚本

标签: asp.net-mvc-3


【解决方案1】:

以下是您可以如何进行的示例:

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
    }
}

【讨论】:

  • 感谢@Darin,您的代码运行良好。我需要确保使用此过滤器的操作方法不会期望 TempData 能够在重定向中存活。
  • 达林,在代码 sn-p 中没有使用“var redirectResult”的目的是什么?我问的原因是我刚刚在一个本土授权属性中找到了这个代码:)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-06-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-03-14
  • 1970-01-01
相关资源
最近更新 更多