我有一个自定义的ModelBinder,我想得到一个动作。因为我想使用反射来获取动作的属性,所以动作名称是不够的。
我的操作方法:
[MyAttribute]
public ActionResult Index([ModelBinder(typeof(MyModelBinder))] MyModel model)
{
}这里是一个典型的ModelBinder
public class MyModelBinder : IModelBinder
{
public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
// here i would like to get the action method and his "MyAttribute"
}
}有什么建议或其他解决方案吗?
非常感谢你提前
发布于 2011-06-02 00:03:31
不,您不能100%确定地从模型绑定器获取当前操作。模型绑定器不是耦合到操作,而是耦合到模型的绑定。例如,您可以调用
TryUpdateMode(model)在选择操作之前,在筛选器中。另请注意,操作方法可能甚至不是可以反映的CLR方法(请参阅http://haacked.com/archive/2009/02/17/aspnetmvc-ironruby-with-filters.aspx)。
我认为真正的问题是,你到底想要实现什么,这是正确的方式吗?如果您希望将来自操作的信息传递给模型绑定器(请注意,如果信息不在模型绑定器中,则模型绑定器应正常降级),则应该使用操作过滤器将信息放入HttpContext.Items (或类似的位置)中,然后让绑定器检索它。
操作筛选器的OnActionExecuting方法接收具有ActionDescriptor的ActionExecutingContext。你可以在这上面调用GetCustomAttributes。
发布于 2011-06-01 20:34:11
你可以试试这个:
var actionName = controllerContext.RouteData.GetRequiredString("action");
var myAttribute = (MyAttribute) Attribute.GetCustomAttribute(controllerContext.Controller.GetMethod(actionName), typeof(MyAttribute));发布于 2016-11-26 18:58:21
您可以覆盖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
}https://stackoverflow.com/questions/6198155
复制相似问题