Вы можете получить атрибуты как действия, так и его параметров, "перехватывая" Controller.ActionInvoker.FindAction()
и сохраняя атрибуты в HttpContext.Current.Items
, как указано здесь, или в расширенном ControllerContext.RequestContext
, следующим образом:
public class MyControllerActionInvoker : ControllerActionInvoker
{
protected override ActionDescriptor FindAction(ControllerContext controllerContext, ControllerDescriptor controllerDescriptor, string actionName)
{
var action = base.FindAction(controllerContext, controllerDescriptor, actionName);
if (action != null)
{
var requestContext = ExtendedRequestContext.Bind(controllerContext);
// if necessary, use action.GetCustomAttributes() to add action's attributes
foreach (var parameter in action.GetParameters())
{
var attr = parameter.GetCustomAttributes(typeof(MyBinderAttribute), false).FirstOrDefault();
if (attr != null)
requestContext.Attributes.Add(parameter.ParameterName, (MyBinderAttribute)attr);
}
}
return action;
}
}
public class ExtendedRequestContext : RequestContext
{
public Dictionary<string, MyBinderAttribute> Attributes { get; private set; }
public static ExtendedRequestContext Bind(ControllerContext controllerContext)
{
var requestContext = new ExtendedRequestContext
{
HttpContext = controllerContext.RequestContext.HttpContext,
RouteData = controllerContext.RequestContext.RouteData,
Attributes = new Dictionary<string, MyBinderAttribute>()
};
controllerContext.RequestContext = requestContext;
return requestContext;
}
}
Вызывающий действие по умолчанию заменен либо в конструкторе вашего контроллера, либо на фабрике пользовательских контроллеров:
public MyController() : base()
{
ActionInvoker = new MyControllerActionInvoker();
}
Кстати, Controller.TempData
уже содержит элемент типа ReflectedParameterDescriptor
, который дает вам доступ к ActionDescriptor
, поэтому приведенный выше код может быть избыточным. Однако будьте осторожны, это зависит от реализации, поэтому может со временем меняться.
Наконец, получите атрибуты из этого хранилища в вашем классе подшивки:
var requestContext = (ExtendedRequestContext)controllerContext.RequestContext;
if (requestContext.Attributes.ContainsKey(bindingContext.ModelName))
{
var attr = requestContext.Attributes[bindingContext.ModelName];
// apply your logic here
}