views:

35

answers:

1

Hi,

I have a BaseViewModel that my View Models all inherit from.

public class MagazineViewModel : BaseOutputViewMode
{
    public string TitleOfPublication { get; set; }
}

In my controller I use a factory method to give the corret View Model back based on an input:

// e.g. viewModel contains an instance of MagazineViewModel 
BaseOutputViewModel viewModel = BaseOutputViewModel.GetOutputViewModel(output);

When I use TryUpdateModel to try and bind to a FormCollection which I know contains a "TitleOfPublication" key, its never set in my view model:

if (!TryUpdateModel(viewModel, form))

I think this is something to do with the DefaultModelBinder using the BaseOutputViewModel to bind FormCollection keys to - it doesn't contain a "TitleOfPublication", the derived MagazineViewModel does.

I'm trying to roll my own model binder, to override the DefaultModelBinder's BindModel behavior. Its all wired in correctly and I can debug into it straight after the TryUpdateModel call:

 public class TestModelBinder : DefaultModelBinder, IFilteredModelBinder
{
    public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
    {
        // Tried the following without success ....
        // 1. Quick hardcoded test
        // bindingContext.ModelType = typeof(MagazineViewModel);
        // 2. Set ModelMetadata, hardcoded test again
        // bindingContext.ModelMetadata = ModelMetadataProviders.Current.GetMetadataForType(null, typeof(MagazineViewModel));
        // 3. Replace the entire context
        // ModelBindingContext context2 = new ModelBindingContext();
        // context2.ModelMetadata = ModelMetadataProviders.Current.GetMetadataForType(null, typeof(MagazineViewModel));
        // context2.ModelName = bindingContext.ModelName;
        // context2.ModelState = bindingContext.ModelState;            
        // context2.ValueProvider = bindingContext.ValueProvider;
        // bindingContext = context2;
    }
}

But I'm not sure how to work with the bindingContext? What needs to be updated so that I can tell the DefaultModelBinder to bind using the derived View Model properties? Or have I just totally mis-understood this!

I did try overriding CreateModel - much like the DerivedTypeModelBinder in MvcContrib, but I think because I'm giving the binder an instance of a model to work with, CreateModel is never called. Used Reflector on the Mvc DLL, theres a "BindComplexModel" that calls CreateModel only if the model is null:

if (model == null)
{
    model = this.CreateModel(controllerContext, bindingContext, modelType);
}

Any pointers greatfully received!

Cheers