Can I do something like this?
[HttpPost]
public ActionResult Index(WizardViewModel wizard, IStepViewModel step)
{
Where I have the following in my global.asax.cs application_start
ModelBinders.Binders.Add(typeof(IStepViewModel), new StepViewModelBinder());
ModelBinders.Binders.Add(typeof(WizardViewModel), new WizardViewModelBinder());
Update
So, I tried to see what is wrong. Here is my new code. It seems that the problem is with this WizardViewModel and it’s binder. What “tells” the application to expect and incoming Wizard model?
[HttpPost]
public ActionResult Index(WizardViewModel wizard)
{
Where I have the following in my global.asax.cs application_start
ModelBinders.Binders.Add(typeof(WizardViewModel), new WizardViewModelBinder());
Complete Binder Code
namespace Tangible.Binders
{
public class StepViewModelBinder : DefaultModelBinder
{
protected override object CreateModel(ControllerContext controllerContext, ModelBindingContext bindingContext, Type modelType)
{
var stepTypeValue = bindingContext.ValueProvider.GetValue("StepType");
var stepType = Type.GetType((string)stepTypeValue.ConvertTo(typeof(string)), true);
var step = Activator.CreateInstance(stepType);
bindingContext.ModelMetadata = ModelMetadataProviders.Current.GetMetadataForType(() => step, stepType);
return step;
}
}
public class WizardViewModelBinder : DefaultModelBinder
{
protected override object CreateModel(ControllerContext controllerContext, ModelBindingContext bindingContext, Type modelType)
{
var wizardValue = bindingContext.ValueProvider.GetValue("wizard");
if (wizardValue != null)
{
var wizardType = Type.GetType((string)wizardValue.ConvertTo(typeof(string)), true);
var wizard = Activator.CreateInstance(wizardType);
bindingContext.ModelMetadata = ModelMetadataProviders.Current.GetMetadataForType(() => wizard, wizardType);
return wizard;
}
else
{
var wizard = new Tangible.Models.WizardViewModel();
wizard.Initialize();
return wizard;
}
}
}
}
The answer is simple – Yes! That is what you SHOULD do when you’ve got custom logic for binding values to your parameters. You can even do that with the use of ModelBinderAttribute, set on each of parameters individually.
And as I see, the mistake is in your model binder code. I don’t have time to check it up, but as far as i remember,
CreateModelis used by model binder to create instance of the model, and then that returned instance is model-binded. So, overrideBindModelinstead ofCreateModeland write your model binding logic inBindModel. That definitely works.