我可以这样做吗?
[HttpPost]
public ActionResult Index(WizardViewModel wizard, IStepViewModel step)
{
在我的global.asax.cs application_start
ModelBinders.Binders.Add(typeof(IStepViewModel), new StepViewModelBinder());
ModelBinders.Binders.Add(typeof(WizardViewModel), new WizardViewModelBinder());
<标题> 更新所以,我试着看看出了什么问题。这是我的新代码。似乎问题是这个WizardViewModel和它的binder。什么"告诉"应用程序期望和传入的向导模型?
[HttpPost]
public ActionResult Index(WizardViewModel wizard)
{
在我的global.asax.cs application_start
ModelBinders.Binders.Add(typeof(WizardViewModel), new WizardViewModelBinder());
完整Binder代码
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;
}
}
}
}
标题>答案很简单——是的!这是你应该做的,当你有自定义逻辑绑定值到你的参数。你甚至可以使用ModelBinderAttribute,单独设置每个参数。
[HttpPost]
public ActionResult Index([ModelBinder(typeof(WizardViewModelBinder))]WizardViewModel wizard,
[ModelBinder(typeof(StepViewModelBinder))]IStepViewModel step)
{ }
在我看来,错误是在你的模型绑定代码。我没有时间检查它,但据我所知,CreateModel
被模型绑定器用来创建模型的实例,然后返回的实例是模型绑定的。因此,覆盖BindModel
而不是CreateModel
,并在BindModel
中编写模型绑定逻辑。
public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
//your model binding logic here
}
我在过去做过类似的事情,我传递一个字符串,然后拆分值
我想说的是:是的!在你的评论中,你担心"许多其他问题"可能会引起麻烦。不知道你脑子里有什么问题,很难帮助你。但你所做的正是模型绑定器设计的目的。而且没有理由,为什么每个操作只能有一个对象
我真的不喜欢ASP。. NET MVC模型绑定要求我跳过来获得一些基本的反序列化。
由于模型绑定不像我所希望的那样透明,所以我简单地构建了一个自定义ActionFilter来解析我想在action方法中反序列化的类型,并使用ServiceStack。我的所有序列化/反序列化需要的文本。
看这里:
https://gist.github.com/3b18a58922fdd8d5a963