假设我有一个如下所示的动作方法:
[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
一起使用。
有什么建议吗?
答案 0 :(得分:4)
首先尝试从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<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();
}
...
}