在 aspnet core 中,访问端点属性的方法很少。在 Core 之前,可以检查某个属性是否应用于端点,如下所示:
actionExecutingContext.ActionDescriptor.GetCustomAttributes(typeof(MyAttribute), true).Length != 0
类似地,在核心中你可以做类似的事情:
((ControllerActionDescriptor)actionExecutingContect.ActionDescriptor).MethodInfo.GetCustomAttributes(typeof(MyAttribute), inherit: true).Length != 0
但是,我读过使用 GetCustomAttributes 很慢,大多数地方建议使用 EndpointMetadata (尽管 Microsoft 明确表示“此 API 用于基础设施,不应由应用程序代码使用。”)或从
获取端点HttpContext
并直接从那里访问 Metadata
:
actionExecutingContext.ActionDescriptor.EndpointMetadata.OfType<MyAttribute>().Count() != 0
或
HttpContext.GetEndpoint().Metadata.OfType<MyAttribute>().Count() != 0
但是,尚不清楚
EndpointMetadata
或 Metadata
是否包含继承的属性,或者是否可以像使用 GetCustomAttributes
那样过滤继承。
是否可以使用
EndpointMetadata
或 Metadata
包含或排除继承属性?
默认情况下,ASP.NET Core 中的 EndpointMetadata 和 HttpContext.GetEndpoint().Metadata 不会自动包含继承的属性。继承属性的包含取决于在应用程序启动和路由配置期间如何发现属性以及如何将属性与端点关联。要包含继承的属性,您需要一个自定义实现,该实现使用反射来识别这些属性并将它们手动添加到端点的元数据中。此方法允许包含继承的属性,但需要额外的设置和配置。
下面是有关处理继承属性的示例代码:
使用反射来识别继承的属性:
var attributes = typeof(MyController).GetMethod("MyAction").GetCustomAttributes(typeof(MyAttribute), inherit: true);
直接操作
EndpointMetadata
不是标准做法,也不受直接支持,您可以使用此信息有条件地在应用程序中应用逻辑,而不是尝试修改元数据集合。例如,如果存在继承属性,您可以在中间件或操作过滤器中使用这种基于反射的方法来应用某些行为。
public class MyAttribute : Attribute { }
public class MyAttributeActionFilter : IActionFilter
{
public void OnActionExecuting(ActionExecutingContext context)
{
var methodInfo = ((ControllerActionDescriptor)context.ActionDescriptor).MethodInfo;
var hasAttribute = methodInfo.GetCustomAttributes(typeof(MyAttribute), true).Any();
if (hasAttribute)
{
// custom code
}
}
public void OnActionExecuted(ActionExecutedContext context) { }
}