我正在实现自定义身份验证过滤器,并使用此处描述的“被动属性”方法: http://blog.ploeh.dk/2014/06/13/passive-attributes/
DI可以按预期工作,但是我不知道如何从控制器本身读取自定义属性?我希望单个动作和整个控制器都支持此功能。
控制器示例:
[TokenAuth] // This attribute not "visible"
public class SupportController : ApiController
{
private ISecurityService SecurityService { get; }
public SupportController(ISecurityService securityService)
{
this.SecurityService = securityService;
}
[TokenAuth] // This attribute works
[HttpGet]
public object StartupData()
{
return "Startup data";
}
}
这是我读取自定义属性的过滤器代码的一部分:
public Task<HttpResponseMessage> ExecuteActionFilterAsync(HttpActionContext actionContext, CancellationToken cancellationToken, Func<Task<HttpResponseMessage>> continuation)
{
var tokenAuthAttribute = actionContext.ActionDescriptor.GetCustomAttributes<TokenAuthAttribute>(true).SingleOrDefault();
// This line below exists unless attribute placed on method/action
if (tokenAuthAttribute == null) return continuation();
var req = actionContext.Request;
有什么方法可以访问控制器的属性?
答案 0 :(得分:2)
动作描述符应使您可以通过ControllerDescriptor
属性访问控制器类型
var actionDescriptor = actionContext.ActionDescriptor;
var tokenAuthAttribute =
actionDescriptor.GetCustomAttributes<TokenAuthAttribute>(true).SingleOrDefault() ??
actionDescriptor.ControllerDescriptor.GetCustomAttributes<TokenAuthAttribute>(true).SingleOrDefault();
//...
上面的代码首先检查动作描述符,如果没有发现,则检查控制器描述符。
答案 1 :(得分:0)
这是一个完整的抽象类,其中的属性作为通用参数。您可以从中继承,指定属性,然后覆盖ExecuteFilterBehavior
。这将检查控制器和方法上的属性。您可以将其修改为仅执行其中一项。
public abstract class ActionFilterBehaviorBase<TAttribute> : IActionFilter where TAttribute : Attribute
{
public Task<HttpResponseMessage> ExecuteActionFilterAsync(HttpActionContext actionContext, CancellationToken cancellationToken, Func<Task<HttpResponseMessage>> continuation)
{
if (ControllerHasAttribute(actionContext) || ActionHasAttribute(actionContext))
{
return ExecuteFilterBehavior(actionContext, cancellationToken, continuation);
}
return continuation();
}
protected abstract Task<HttpResponseMessage> ExecuteFilterBehavior(HttpActionContext actionContext, CancellationToken cancellationToken,
Func<Task<HttpResponseMessage>> continuation);
public virtual bool AllowMultiple { get; } = false;
private bool ControllerHasAttribute(HttpActionContext actionContext)
{
return actionContext
.ControllerContext.Controller.GetType()
.GetCustomAttributes(false)
.Any(attribute => attribute.GetType().IsAssignableFrom(typeof(TAttribute)));
}
private bool ActionHasAttribute(HttpActionContext actionContext)
{
return actionContext
.ActionDescriptor
.GetCustomAttributes<TAttribute>()
.Any();
}
}
更多详细信息here。