views:

2555

answers:

3

Hello,

I have a type:

public class IssueForm
{
    Order Order {get; set;}
    Item Item {get; set;}
    Range Range {get; set;}
}

I created a custom model binder due to requirements on Order and Item, but Range could still use the Default Model Binder.

Is there a way from within my custom model binder to call the default model binder to return a Range object? I think I just have to just setup ModelBindingContext correctly, but I don't know how.


EDIT

Looking at the first comment and answer -- it seems like inheriting from the default model binder could be useful.

To add more specifics for my setup so far I have:

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
    }
}

This might be a stupid way of doing it... this is my first model binder. Just pointing out my current implementation.


EDIT #2

So the answers to override BindProperty will work if I can hook into like a "I'm all done binding" method and call the Factory method with the properties.

I guess I really should look at the DefaultModelBinder implementation and quit being stupid.

+9  A: 

Try something like this:

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);
    }

}
eu-ge-ne
+16  A: 

override the BindProperty from the DefaultModelBinder:

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
            }
        }
Marwan Aouida
+1 for inspedcting property type instead of the name. Blame magic strings!
Anton
+2  A: 

I think I would have registered two different custom model binders, one for Order and one for Item, and let the default model binder handle the Range and the IssueForm.

Konstantin
Yes, obviously its been awhile since I asked this question. I ended up looking at the DefaultModelBinder code and realizing the recursive nature of model binding. I didn't realize with a complex type containing other complex types I could just define a model binder for each one individually. I instead thought the complex parent would have to know the details of each complex child.
eyston