ASP.NET MVC - 混合自定义和默认模型绑定

ano*_*ous 38 asp.net-mvc modelbinders

我有一个类型:

public class IssueForm
{
    Order Order {get; set;}
    Item Item {get; set;}
    Range Range {get; set;}
}
Run Code Online (Sandbox Code Playgroud)

由于Order和Item的要求,我创建了一个自定义模型绑定器,但Range仍然可以使用Default Model Binder.

我的自定义模型绑定器中是否有一种方法可以调用默认模型绑定器来返回Range对象?我想我只需要正确设置ModelBindingContext,但我不知道如何.


编辑

查看第一个评论和答案 - 似乎从默认模型绑定器继承可能很有用.

到目前为止为我的设置添加更多细节我有:

public IssueFormModelBinder : IModelBinder
{
    public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
    {
        Order = //code to pull the OrderNumber from the context and create an Order
        Item = //code to pull the ItemNumber from the context and create an Item

        IssueForm form = IssueFormFactory.Create(Order, Item);

        form.Range = // ** I'd like to replace my code with a call to the default binder **

        return form
    }
}
Run Code Online (Sandbox Code Playgroud)

这可能是一种愚蠢的方式......这是我的第一个模型绑定器.只是指出我目前的实施.


编辑#2

因此,如果我可以像"我完成所有绑定"方法一样挂钩并使用属性调用Factory方法,则覆盖BindProperty的答案将起作用.

我想我真的应该看看DefaultModelBinder实现并退出愚蠢.

小智 52

从DefaultModelBinder重写BindProperty:

public class CustomModelBinder:DefaultModelBinder
        {
            protected override void BindProperty( ControllerContext controllerContext, ModelBindingContext bindingContext, System.ComponentModel.PropertyDescriptor propertyDescriptor )
            {
                if (propertyDescriptor.PropertyType == typeof(Range))
                {
                    base.BindProperty(controllerContext, bindingContext, propertyDescriptor);
                }
                // bind the other properties here
            }
        }
Run Code Online (Sandbox Code Playgroud)

  • +1用于保护属性类型而不是名称.责怪魔法弦! (22认同)

eu-*_*-ne 25

尝试这样的事情:

public class CustomModelBinder :  DefaultModelBinder {
    protected override void BindProperty(ControllerContext controllerContext, ModelBindingContext bindingContext, PropertyDescriptor propertyDescriptor) {
        if(propertyDescriptor.Name == "Order") {
            ...
            return;
        }

        if(propertyDescriptor.Name == "Item") {
            ...
            return;
        }

        base.BindProperty(controllerContext, bindingContext, propertyDescriptor);
    }

}
Run Code Online (Sandbox Code Playgroud)


Kon*_*tin 6

我想我会注册两个不同的自定义模型绑定器,一个用于Order,一个用于Item,并让默认模型绑定器处理Range和IssueForm.

  • 是的,显然自从我提出这个问题以来已经有一段时间了.我最终查看了DefaultModelBinder代码并实现了模型绑定的递归特性.我没有意识到包含其他复杂类型的复杂类型我可以单独为每个类型定义一个模型绑定器.我反而认为复杂的父母必须知道每个复杂孩子的细节. (4认同)