您可以覆盖ControllerActionInvoker.FindAction()
得到行动的属性,如这里所提到的,或延长ControllerContext.RequestContext
其存储在HttpContext.Current.Items
,如下:
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
}
这是'MyAttribute'动作过滤器或一个普通的CLR属性?它的目的是什么?为什么你需要将它与模型绑定器绑在一起? – 2011-06-01 12:59:21
是的,MyAttribute是一个CLR属性。我会用“信息”来签名该方法,因为没有办法用[ModelBinder(typeof(MyModelBinder))]传递参数。 – dknaack 2011-06-01 13:09:32
@dknaack,有一种方法:您可以使用自定义模型联编程序提供程序。 – 2011-06-01 14:25:45