首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Asp.NET MVC ModelBinder,获取操作方法

Asp.NET MVC ModelBinder,获取操作方法
EN

Stack Overflow用户
提问于 2011-06-01 16:14:40
回答 3查看 2.7K关注 0票数 9

我有一个自定义的ModelBinder,我想得到一个动作。因为我想使用反射来获取动作的属性,所以动作名称是不够的。

我的操作方法:

代码语言:javascript
复制
[MyAttribute]
public ActionResult Index([ModelBinder(typeof(MyModelBinder))] MyModel model)
{
}

这里是一个典型的ModelBinder

代码语言:javascript
复制
public class MyModelBinder : IModelBinder
{
    public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) 
    {
        // here i would like to get the action method and his "MyAttribute"
    }
}

有什么建议或其他解决方案吗?

非常感谢你提前

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2011-06-02 00:03:31

不,您不能100%确定地从模型绑定器获取当前操作。模型绑定器不是耦合到操作,而是耦合到模型的绑定。例如,您可以调用

代码语言:javascript
复制
TryUpdateMode(model)

在选择操作之前,在筛选器中。另请注意,操作方法可能甚至不是可以反映的CLR方法(请参阅http://haacked.com/archive/2009/02/17/aspnetmvc-ironruby-with-filters.aspx)。

我认为真正的问题是,你到底想要实现什么,这是正确的方式吗?如果您希望将来自操作的信息传递给模型绑定器(请注意,如果信息不在模型绑定器中,则模型绑定器应正常降级),则应该使用操作过滤器将信息放入HttpContext.Items (或类似的位置)中,然后让绑定器检索它。

操作筛选器的OnActionExecuting方法接收具有ActionDescriptor的ActionExecutingContext。你可以在这上面调用GetCustomAttributes。

票数 4
EN

Stack Overflow用户

发布于 2011-06-01 20:34:11

你可以试试这个:

代码语言:javascript
复制
var actionName = controllerContext.RouteData.GetRequiredString("action");
var myAttribute = (MyAttribute) Attribute.GetCustomAttribute(controllerContext.Controller.GetMethod(actionName), typeof(MyAttribute));
票数 1
EN

Stack Overflow用户

发布于 2016-11-26 18:58:21

您可以覆盖ControllerActionInvoker.FindAction()以获取操作的属性,并将其存储在此处提到的HttpContext.Current.Items或扩展的ControllerContext.RequestContext中,如下所示:

代码语言:javascript
复制
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;
    }
}

默认动作调用器在控制器的构造函数或自定义控制器工厂中被替换:

代码语言:javascript
复制
public MyController() : base()
{
    ActionInvoker = new MyControllerActionInvoker();
}

顺便说一句,Controller.TempData已经包含了一个ReflectedParameterDescriptor类型的项目,它允许您访问ActionDescriptor,因此上面的代码可能是多余的。但是,要注意这是特定于实现的,因此可能会随着时间的推移而改变。

最后,从绑定器类中的存储中获取属性:

代码语言:javascript
复制
var requestContext = (ExtendedRequestContext)controllerContext.RequestContext;
if (requestContext.CustomAttribute != null)
{
    // apply your logic here
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/6198155

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档