Вы можете переопределить ControllerActionInvoker.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);
var attr = action.GetCustomAttributes(typeof(MyAttribute), false).FirstOrDefault();
if (attr != null)
requestContext.CustomAttribute = (MyAttribute)attr;
}
return action;
}
}
public class ExtendedRequestContext : RequestContext
{
public MyAttribute CustomAttribute { get; set; }
public static ExtendedRequestContext Bind(ControllerContext controllerContext)
{
var requestContext = new ExtendedRequestContext
{
HttpContext = controllerContext.RequestContext.HttpContext,
RouteData = controllerContext.RequestContext.RouteData
};
controllerContext.RequestContext = requestContext;
return requestContext;
}
}
По умолчанию вызыватель действия заменяется либов конструкторе вашего контроллера или на фабрике пользовательских контроллеров:
public MyController() : base()
{
ActionInvoker = new MyControllerActionInvoker();
}
Кстати, Controller.TempData
уже содержит элемент типа ReflectedParameterDescriptor
, который дает вам доступ к ActionDescriptor
, поэтому приведенный выше кодможет быть избыточным.Однако имейте в виду, что это зависит от реализации, поэтому может со временем меняться.
Наконец, получите атрибут из этого хранилища в своем классе связующего:
var requestContext = (ExtendedRequestContext)controllerContext.RequestContext;
if (requestContext.CustomAttribute != null)
{
// apply your logic here
}