【问题标题】:How to pass variables to custom ActionFilterAttribute如何将变量传递给自定义 ActionFilterAttribute
【发布时间】:2015-11-17 16:06:40
【问题描述】:

将变量传递给我的MyCustomAttribute 类有哪些选择?

目前该类定义为:

public class MyCustomAttribute : ActionFilterAttribute
{
    public string MyIDParam { get; set; }

    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        var myID = filterContext.ActionParameters[MyIDParam] as Int32?;

        // logic
    }
}

现在在我的控制器中我有这个:

[MyCustomAttribute(MyIDParam = "id")]
public ActionResult Report(int id)
{
    Guid userId = GetUserInfo();

    // logic
}

在这种情况下,我希望能够将 iduserId 传递给 MyCustomAttribute 类。

这可能吗? MyCustomAttribute 不是在Report 方法的内容之前执行吗?

【问题讨论】:

  • 是的,你不能那样做。就像你说的,动作过滤器代码是在动作之前执行的。
  • 您可以使用请求上下文间接获取它:filterContext.HttpContext.Request.Params["id"]
  • @PaulDS 那么通过userId 怎么样?就像我说的,这是不可能的。
  • 哇,有些 cmets 是不正确的。仅仅因为动作没有执行并不意味着值不存在。甚至在构造控制器之前,用户就可以使用 long。路由值(控制器方法参数)也必须在构造控制器之前创建,因为它们用于从 MapRoutes 中识别控制器/动作。
  • 这包括参数,因为可以创建 Route Constraint 来询问参数以验证 MapRoute 是否可以处理请求。

标签: c# asp.net-mvc action-filter


【解决方案1】:

将变量传递到 MyCustomAttribute 类有哪些选项?

你正在编写一个自定义的ActionFilter,MVC 通过ActionExecutingContext。该变量包含大量信息供您使用。

public class MyCustomAttribute : ActionFilterAttribute
{
  public override void OnActionExecuting(ActionExecutingContext filterContext)
  {
    var myID = filterContext
      .RouteData["id"] as int?

    var user = filterContext.Controller.User;
  }
}

在这种情况下,我希望能够将“id”和“userId”传递给 MyCustomAttribute 类。

不,您不能将它们传入,您必须从 ActionExecutingContext 中检索它们。

MyCustomAttribute 不是在 Report 方法的内容之前执行吗?

也许?取决于您的覆盖方法。

ActionFilterAttribute 有几个不同的执行点。这是一个细分:

ActionFilterAttribute.OnActionExecuting()  // Action Filter

public ActionResult Report(int id) // MVC Action is Called

ActionFilterAttribute.OnActionExecuted()  // Action Filter

ActionFiltrAttribute.OnResultExecuting()  // Action Filter

ActionResult.Execute() // MVC ActionResult Execute is Called

ActionFilterAttribute.OnResultExecuted()  // Action Filter

你可以看到 these methods have been available to access to all this data 版本 1 开始。

【讨论】:

    【解决方案2】:

    您可以通过在自定义属性中添加对引用操作参数的支持来获得该功能。

    [MyCustomAttribute("The parameter for id is {id}")]
    public ActionResult Report(int id)
    {
        Guid userId = GetUserInfo();
    
        ... logic ...
    }
    

    在运行时,您的自定义属性可以将引用参数的值替换为占位符。
    所以为了实现这个功能,你只需要挂钩到 ActionExecuting 方法来获取那些动作参数:

        private IDictionary<string, object> _parameters;
        public override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            _parameters = filterContext.ActionParameters;
            base.OnActionExecuting(filterContext);
        }
    

    然后在您的OnActionExecuted 方法中,您可以创建一个变量来处理字段。然后您可以遍历字典中的每个参数并替换为参数的值:

    public override void OnActionExecuted(ActionExecutedContext filterContext)
    {
        var data = MyIDParam;
        foreach(var kvp in _parameters)
        {
            data = data.Replace("{" + kvp.Key + "}", 
               kvp.Value.ToString());
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2019-11-07
      • 1970-01-01
      • 2017-07-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-12-22
      • 1970-01-01
      相关资源
      最近更新 更多