正在检索操作签名自定义属性

本文关键字:自定义属性 操作 检索 | 更新日期: 2023-09-27 18:20:46

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

    [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一起工作还不清楚。

有什么建议吗?

正在检索操作签名自定义属性

首先尝试将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的具体类型似乎取决于全局Web API服务是否包含ITraceWriter的实例(请参阅:ASP.NET Web API中的跟踪)。

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

为了解决这个问题,我们需要检查ActionDescriptor是否实现了IDecorator<HttpActionDescriptor>接口:

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();
  }
  ...
}