【问题标题】:Retrieving Action Signature Custom Attributes检索操作签名自定义属性
【发布时间】:2014-09-04 22:52:42
【问题描述】:

假设我有一个如下所示的操作方法:

    [return: Safe]
    public IEnumerable<string> Get([Safe] SomeData data)
    {
        return new string[] { "value1", "value2" };
    }

[Safe] 属性是我创建的自定义属性。我想创建一个 ActionFilter,它可以在参数或返回类型上定位 [Safe] 属性。我已经为 OnActionExecuting 覆盖中的参数工作,因为我可以像这样访问我的 [Safe] 属性:

//actionContext is of type HttpActionContext and is a supplied parameter.
foreach (var parm in actionContext.ActionDescriptor.ActionBinding.ParameterBindings)
{
    var safeAtts = parm.Descriptor.GetCustomAttributes<SafeAttribute>().ToArray();
}

但是如何检索放置在返回类型上的 [Safe] 属性?

采用这种方法可能会有所探索:

ModelMetadataProvider meta = actionContext.GetMetadataProvider();

但如果这确实有效,尚不清楚如何使其与ModelMetadataProvider 一起工作。

有什么建议吗?

【问题讨论】:

    标签: c# reflection asp.net-web-api


    【解决方案1】:

    首先尝试将ActionDescriptor 属性从HttpActionContext 转换为ReflectedHttpActionDescriptor。 然后使用MethodInfo 属性通过其ReturnTypeCustomAttributes 属性检索您的自定义属性。

    public override void OnActionExecuting(HttpActionContext actionContext)
    {
      ...
      var reflectedActionDescriptor = actionContext.ActionDescriptor as ReflectedHttpActionDescriptor;
      if (reflectedActionDescriptor != null)
      {
        // get the custom attributes applied to the action return value
        var attrs = reflectedActionDescriptor
                      .MethodInfo
                      .ReturnTypeCustomAttributes
                      .GetCustomAttributes(typeof (SafeAttribute), false)
                      .OfType<SafeAttribute>()
                      .ToArray();
      }
      ...
    }
    

    更新:启用跟踪

    ActionDescriptor 的具体类型似乎取决于Global Web API Services 是否包含ITraceWriter 的实例(请参阅:Tracing in ASP.NET Web API)。

    默认情况下,ActionDescriptor 的类型为 ReflectedHttpActionDescriptor。但是当启用跟踪时——通过调用config.EnableSystemDiagnosticsTracing()——ActionDescriptor 将被包裹在HttpActionDescriptorTracer 类型中

    要解决这个问题,我们需要检查ActionDescriptor 是否实现IDecorator&lt;HttpActionDescriptor&gt; 接口:

    public override void OnActionExecuting(HttpActionContext actionContext)
    {
      ...
      ReflectedHttpActionDescriptor reflectedActionDescriptor;
      
      // Check whether the ActionDescriptor is wrapped in a decorator or not.
      var wrapper = actionContext.ActionDescriptor as IDecorator<HttpActionDescriptor>;
      if (wrapper != null)
      {
        reflectedActionDescriptor = wrapper.Inner as ReflectedHttpActionDescriptor;
      }
      else
      {
        reflectedActionDescriptor = actionContext.ActionDescriptor as ReflectedHttpActionDescriptor;
      }
      
      if (reflectedActionDescriptor != null)
      {
        // get the custom attributes applied to the action return value
        var attrs = reflectedActionDescriptor
                      .MethodInfo
                      .ReturnTypeCustomAttributes
                      .GetCustomAttributes(typeof (SafeAttribute), false)
                      .OfType<SafeAttribute>()
                      .ToArray();
      }
      ...
    }
    

    【讨论】:

    • 不好。 ActionDescriptor 不会转换为 ReflectedHttpActionDescriptor。它实际上是 HttpActionDescriptorTracer 类型,我认为是内部的。
    • @Brent 抱歉回复晚了。我想我找到了问题所在。这与追踪有关。请查看我的更新答案。
    猜你喜欢
    • 1970-01-01
    • 2011-04-24
    • 2021-06-05
    • 1970-01-01
    • 2016-07-26
    • 2019-04-05
    • 2015-12-17
    • 2011-09-12
    • 1970-01-01
    相关资源
    最近更新 更多