0

我有 ActionFilterAttribute 如下

class MyCustomRouteConstraint : ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        if (something == 1) //i know there is no something variable
        { 
           // do something
        }
        base.OnActionExecuting(filterContext);
    }

}

正如您在我的代码中看到的那样,没有命名为某物的变量。但我想在我的操作中使用名为 something 的变量。

    public ActionResult Index()
    {
        int something = 1;
        return View();
    }

    public ActionResult About()
    {
        int something = 2;
        return View();
    }

    public ActionResult Contact()
    {
        int something = 1;
        return View();
    }
4

5 回答 5

1

我认为您需要的是OnActionExecuted。我没有测试过。

class MyCustomRouteConstraint : ActionFilterAttribute
{
    public override void OnActionExecuted(ActionExecutedContext filterContext)
    {
        var something = Convert.ToInt32(filterContext.RouteData.Values["something"]);
        if(something == 1)
        {
            //do something
        }
        base.OnActionExecuting(filterContext);
    }
}
于 2013-08-12T15:28:31.587 回答
0

我使用结构映射依赖注入来做到这一点。请参阅此处的一些片段:

namespace something.Infrastructure.ActionFilters {

  public class PlatformAuthorizeAttribute : AuthorizeAttribute
  {
      public IRepository<User> UserRepo { get; set; }

      public override void OnAuthorization(AuthorizationContext filterContext)
      {
          base.OnAuthorization(filterContext);

          if (WebSecurity.Initialized && filterContext.HttpContext.User.Identity.IsAuthenticated)
          {
              if (filterContext.HttpContext.User.IsInRole("Banned"))
              {
                  WebSecurity.Logout();
                  filterContext.Result = new RedirectToRouteResult(
                      new RouteValueDictionary
                          {
                            {"Controller", "Home"},
                            {"Action", "Banned"},
                            {"Area", ""}
                          });
              }
              UserRepo.Dispose();
              UserRepo = null;
          }  
      }
  }
}

然后在您的 IoC 结构映射类中初始化以下映射:

public static class IoC
{
    public static IContainer Initialize()
    {
        ObjectFactory.Initialize(x =>
            {
                x.Scan(scan =>
                    {
                        scan.TheCallingAssembly();
                        scan.WithDefaultConventions();
                    });
                x.SetAllProperties(pset =>
                    {
                        pset.WithAnyTypeFromNamespace("something.Infrastructure.ActionFilters");
                        pset.OfType<IRepository<User>>();
                    });
            });
        return ObjectFactory.Container;
    }
}

我认为这是为您的操作过滤器提供属性的最干净的方法。请注意,在我的示例中,我使用了自定义 AuthorizeAttribute。您需要将其更改为 ActionFilterAttribute 并使用 OnActionExecuting 方法覆盖来访问属性。

于 2013-08-12T14:24:37.280 回答
0

OnActionExecuting 在操作方法执行之前由 ASP.NET MVC 框架调用。所以在动作主体中初始化你的变量是没有意义的。但是,如果您要覆盖一些在操作方法执行后调用的方法,您可能可以使用 ViewBag 来初始化控制器中的变量,然后使用 filterContext 获取它的值。

于 2013-08-12T14:27:12.880 回答
0

您也为此使用 ViewBag。

    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        filterContext.Controller.ViewBag.SommeVariable = "Test";
    }

在你的行动中

    public ActionResult Index()
    {
        var variable = ViewBag.SommeVariable;
        return View();
    }
于 2013-08-12T14:29:33.783 回答
-1

利用HttpContext.Items

HttpContext.Items["something"] = 1;

在 ActionFilter 中,您可以通过以下方式访问它:

var something = (int)filterContext.HttpContext.Items["something"];

但是,您的动作过滤器示例是 OnActionExecuting;这将在您的任何索引/关于操作执行之前执行。因此,您应该根据需要在其他地方初始化“某物”(例如,在控制器的 OnActionExecuting 方法内部)。

于 2013-08-12T14:21:53.393 回答