この記事 に基づいて、コントローラーとコントローラーのアクションでマークされている属性を処理できるASP.NET CoreのIActionFilter
実装を作成しようとしています。コントローラーの属性の読み取りは簡単ですが、アクションメソッドで定義された属性を読み取る方法を見つけることができません。
私が今持っているコードは次のとおりです。
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();
}
}
私の質問は次のとおりです。ASP.NETCore MVCでアクションメソッドの属性を読み取るにはどうすればよいですか。
MethodInfo
クラスを介してアクションのControllerActionDescriptor
にアクセスできます。
public void OnActionExecuting(ActionExecutingContext context)
{
var controllerActionDescriptor = context.ActionDescriptor as ControllerActionDescriptor;
if (controllerActionDescriptor != null)
{
var actionAttributes = controllerActionDescriptor.MethodInfo.GetCustomAttributes(inherit: true);
}
}
MVC 5 ActionDescriptor
属性へのアクセスを許可するICustomAttributeProvider
インターフェイスの実装に使用されるクラス。何らかの理由で、これはASP.NET Core MVC ActionDescriptor
クラスで削除されました。
Henk Mollemaのソリューションに基づいた元のGetCustomAttributes
を模倣する拡張メソッドを作成しました。
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>();
}
それが役に立てば幸い。
私のカスタム属性は、ActionFilterAttributeを継承しています。コントローラーに配置しましたが、必要のないアクションが1つあります。 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;
}
}
}
}
Henk Mollena による回答
public void OnActionExecuting(ActionExecutingContext context) { var controllerActionDescriptor = context.ActionDescriptor as ControllerActionDescriptor; if (controllerActionDescriptor != null) { var controllerAttributes = controllerActionDescriptor .MethodInfo .GetCustomAttributes(inherit: true); } }
属性の存在を確認する場合は正しい方法ですアクションに適用。
属性の存在を確認したい場合に備えて、彼の答えに追加したいだけですコントローラに適用
_public void OnActionExecuting(ActionExecutingContext context)
{
var controllerActionDescriptor = context.ActionDescriptor as ControllerActionDescriptor;
if (controllerActionDescriptor != null)
{
var actionAttributes = controllerActionDescriptor.ControllerTypeInfo.GetCustomAttributes(inherit: true);
}
}
_
また、GetCustomAttributes関数のオーバーロード関数を使用して、特定の属性を取得できます。
var specificAttribute = GetCustomAttributes(typeof(YourSpecificAttribute), true).FirstOrDefault()