【问题标题】:How to get filter to redirect to another action?如何让过滤器重定向到另一个动作?
【发布时间】:2010-10-07 18:01:22
【问题描述】:

RedirectToAction 是受保护的,我们只能在操作中使用它。但是如果我想在过滤器中重定向呢?

public class IsGuestAttribute: ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        if (!Ctx.User.IsGuest) 
            filterContext.Result = (filterContext.Controller as Controller)
                .RedirectToAction("Index", "Home");
    }
}

【问题讨论】:

    标签: asp.net-mvc redirecttoaction


    【解决方案1】:

    RedirectToAction 只是构造RedirectToRouteResult() 的辅助方法,因此您只需创建一个新的RedirectToRouteResult(),并传递带有您操作的值的RouteValueDictionary()

    基于下面评论中@Domenic 的代码的完整示例:

    public class IsGuestAttribute: ActionFilterAttribute
    {
        public override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            if (!Ctx.User.IsGuest) 
            {
                filterContext.Result = new RedirectToRouteResult(
                    new RouteValueDictionary 
                    { 
                        { "controller", "Home" }, 
                        { "action", "Index" } 
                    });
            }
        }
    }
    

    【讨论】:

    • 你也可以把这段代码放在OnException方法里,只要你设置filterContext.ExceptionHandled = true;
    【解决方案2】:

    这是一个代码示例:

    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
    
        if (!Ctx.User.IsGuest)
        {
            RouteValueDictionary redirectTargetDictionary = new RouteValueDictionary();
            redirectTargetDictionary.Add("action", "Index");
            redirectTargetDictionary.Add("controller", "Home");
    
            filterContext.Result = new RedirectToRouteResult(redirectTargetDictionary);
        }
    }
    

    【讨论】:

    • 或者只是new RedirectToRouteResult(new RouteValueDictionary { { "controller", "Home" }, {"action", "HomePage" } })
    • 如果你能用绿色的锐化下划线说出那条评论就好了
    • 你也可以把这段代码放在OnException方法里,只要你设置filterContext.ExceptionHandled = true;
    【解决方案3】:

    我知道我参加聚会有点晚了,但是我使用了 veggerby 的解决方案并构建了一个可能对某些人有用的帮助程序类,所以我想在这里提供它:

    public static class ActionFilterHelpers
    {
        public static void Redirect(this ActionExecutingContext filterContext, String controller, String action, object routeValues)
        {
            filterContext.Result = Redirect(controller, action, routeValues);
        }
    
        public static ActionResult Redirect(String controller, String action, object routeValues)
        {
            var routeValues = new RouteValueDictionary();
    
            routeValues["controller"] = controller;
            routeValues["action"] = action;
    
            foreach (var keyValue in new ObjectDictionary(routeValues))
                routeValues.Add(keyValue.Key, keyValue.Value);
    
            return new RedirectToRouteResult(routeValues);
        }
    }
    

    我提供了一个返回重定向ActionResult 的静态方法和一个扩展filterContext 的扩展方法。希望有人觉得这很有用。

    ObjectDictionary 是一个使用反射从构造它的对象的属性创建字典的类。我没有包含该代码,因为我相信在框架的某个地方有更好的方法来做到这一点。我还没有找到,但我不希望别人继承我的潜在错误。

    【讨论】:

      【解决方案4】:

      安全/授权/身份验证过滤器应使用AuthorizeAttributeIAuthorizationFilter

      public class IsGuestAttribute: AuthorizeAttribute, IAuthorizationFilter
      {
          public void OnResultExecuted(ResultExecutedContext filterContext)
          {
          }
          public void OnActionExecuting(ActionExecutingContext filterContext)
          {
              if (!Ctx.User.IsGuest) 
              {
                  filterContext.Result = new RedirectToRouteResult(
                      new RouteValueDictionary 
                      { 
                          { "controller", "Home" }, 
                          { "action", "Index" } 
                      });
              }
          }
      }
      

      【讨论】:

        【解决方案5】:

        用法: filterContext.RedirectToAction("Login", "Account");

        这是我编写的一个辅助类,其中包含一些扩展方法,用于在更多地方提供 RedirectToAction 功能。这对于 OP 来说为时已晚,但希望它可以帮助某人!

        public static class RedirectHelper
        {
            // RedirectToAction Extension Methods
            public static void RedirectToAction(this HttpResponseBase response, String action, String controller, object routeValues = null, bool endResponse = false)
            {
                response.RedirectToRoute(CreateRoute(action, controller, routeValues));
                if (endResponse) response.End();
            }
            public static void RedirectToAction(this HttpResponse response, String action, String controller, object routeValues = null, bool endResponse = false)
            {
                response.RedirectToRoute(CreateRoute(action, controller, routeValues));
                if (endResponse) response.End();
            }
            public static void RedirectToAction(this ActionExecutingContext filterContext, String action, String controller, object routeValues = null, bool endResponse = false)
            {
                if (endResponse) filterContext.HttpContext.Response.RedirectToAction(action, controller, routeValues, true);
                else filterContext.Result = new RedirectToRouteResult(CreateRoute(action, controller, routeValues));
            }
            public static void RedirectToAction(this ExceptionContext filterContext, String action, String controller, object routeValues = null, bool endResponse = false)
            {
                if (endResponse) filterContext.HttpContext.Response.RedirectToAction(action, controller, routeValues, true);
                else {
                    filterContext.ExceptionHandled = true;
                    filterContext.Result = new RedirectToRouteResult(CreateRoute(action, controller, routeValues));
                }
            }
            // Route Value Derivation
            public static RouteValueDictionary CreateRoute(String action, String controller, object routeValues = null)
            {
                RouteValueDictionary result = routeValues != null ? 
                    HtmlHelper.AnonymousObjectToHtmlAttributes(routeValues) : 
                    new RouteValueDictionary();
                result["controller"] = controller;
                result["action"] = action;
                return result;
            }
        }
        

        还有更多 ControllerContexts 不包括在内,但根据您的需要添加您自己的应该相当容易。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2014-04-26
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2017-10-25
          • 1970-01-01
          • 1970-01-01
          • 2011-07-24
          相关资源
          最近更新 更多