Ste*_*ven 48 .net c# asp.net-core-mvc asp.net-core
基于这篇文章,我正在尝试IActionFilter
为ASP.NET Core 创建一个实现,它可以处理控制器上标记的属性和控制器的操作.虽然读取控制器的属性很容易,但我无法找到一种方法来读取action方法中定义的属性.
这是我现在的代码:
public sealed class ActionFilterDispatcher : IActionFilter
{
private readonly Func<Type, IEnumerable> container;
public ActionFilterDispatcher(Func<Type, IEnumerable> container)
{
this.container = container;
}
public void OnActionExecuting(ActionExecutingContext context)
{
var attributes = context.Controller.GetType().GetCustomAttributes(true);
attributes = attributes.Append(/* how to read attributes from action method? */);
foreach (var attribute in attributes)
{
Type filterType = typeof(IActionFilter<>).MakeGenericType(attribute.GetType());
IEnumerable filters = this.container.Invoke(filterType);
foreach (dynamic actionFilter in filters)
{
actionFilter.OnActionExecuting((dynamic)attribute, context);
}
}
}
public void OnActionExecuted(ActionExecutedContext context)
{
throw new NotImplementedException();
}
}
Run Code Online (Sandbox Code Playgroud)
我的问题是:如何在ASP.NET Core MVC中读取action方法的属性?
Hen*_*ema 61
您可以MethodInfo
通过ControllerActionDescriptor
课程访问该操作:
public void OnActionExecuting(ActionExecutingContext context)
{
var controllerActionDescriptor = context.ActionDescriptor as ControllerActionDescriptor;
if (controllerActionDescriptor != null)
{
var actionAttributes = controllerActionDescriptor.MethodInfo.GetCustomAttributes(inherit: true);
}
}
Run Code Online (Sandbox Code Playgroud)
MVC 5 ActionDescriptor
类用于实现ICustomAttributeProvider
访问属性的接口.出于某种原因,这已在ASP.NET Core MVC ActionDescriptor
类中删除.
Joa*_*oas 23
调用GetCustomAttributes
方法和/或类很慢(呃)。你应该不会调用GetCustomAttributes
,因为.NET 2.2的核心,这@Henk默勒马是在暗示每个请求。(有一个例外,我稍后会解释)
相反,在应用程序启动时,asp.net 核心框架将为您调用GetCustomAttributes
操作方法和控制器,并将结果存储在元数据中。EndPoint
然后,您可以通过访问您的asp.net的核心过滤器这些元数据EndpointMetadata
属性的的ActionDescriptor
类。
public class CustomFilter : IActionFilter
{
public void OnActionExecuting(ActionExecutingContext context)
{
// Get attributes on the executing action method and it's defining controller class
var attributes = context.ActionDescriptor.EndpointMetadata.OfType<MyCustomAttribute>();
}
public void OnActionExecuted(ActionExecutedContext context)
{
}
}
Run Code Online (Sandbox Code Playgroud)
如果您无权访问来自 asp.net core 3.0的ActionDescriptor
(例如:因为您从中间件而不是过滤器操作),您可以使用GetEndpoint
扩展方法访问它的Metadata
. 有关更多信息,请参阅此github 问题。
public class CustomMiddleware
{
private readonly RequestDelegate next;
public CustomMiddleware(RequestDelegate next)
{
this.next = next;
}
public async Task Invoke(HttpContext context)
{
// Get the enpoint which is executing (asp.net core 3.0 only)
var executingEnpoint = context.GetEndpoint();
// Get attributes on the executing action method and it's defining controller class
var attributes = executingEnpoint.Metadata.OfType<MyCustomAttribute>();
await next(context);
// Get the enpoint which was executed (asp.net core 2.2 possible after call to await next(context))
var executingEnpoint2 = context.GetEndpoint();
// Get attributes on the executing action method and it's defining controller class
var attributes2 = executingEnpoint.Metadata.OfType<MyCustomAttribute>();
}
}
Run Code Online (Sandbox Code Playgroud)
如上所述,端点元数据包含操作方法及其定义控制器类的属性。这意味着,如果您想显式忽略应用于控制器类或操作方法的属性,则必须使用GetCustomAttributes
. 在 asp.net core 中几乎从来没有这种情况。
我创建了一个扩展方法,模仿GetCustomAttributes
Henk Mollema解决方案中的原始方法.
public static IEnumerable<T> GetCustomAttributes<T>(this Microsoft.AspNet.Mvc.Abstractions.ActionDescriptor actionDescriptor) where T : Attribute
{
var controllerActionDescriptor = actionDescriptor as ControllerActionDescriptor;
if (controllerActionDescriptor != null)
{
return controllerActionDescriptor.MethodInfo.GetCustomAttributes<T>();
}
return Enumerable.Empty<T>();
}
Run Code Online (Sandbox Code Playgroud)
希望能帮助到你.
我的自定义属性是从ActionFilterAttribute继承的.我把它放在我的控制器上,但有一个动作不需要它.我想使用AllowAnonymous
属性忽略它,但它不起作用.因此,我在自定义属性中添加此代码段以查找AllowAnonymous
并跳过它.您可以在for循环中获取其他内容.
public class PermissionAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext context)
{
foreach (var filterDescriptors in context.ActionDescriptor.FilterDescriptors)
{
if (filterDescriptors.Filter.GetType() == typeof(AllowAnonymousFilter))
{
return;
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
21006 次 |
最近记录: |