Asp.net mvc ASP.NET模型绑定到基类型

Asp.net mvc ASP.NET模型绑定到基类型,asp.net-mvc,types,derived,defaultmodelbinder,Asp.net Mvc,Types,Derived,Defaultmodelbinder,我的视图模型都继承自一个BaseViewModel public class MagazineViewModel : BaseOutputViewMode { public string TitleOfPublication { get; set; } } 在我的控制器中,我使用工厂方法根据输入返回正确的视图模型: // e.g. viewModel contains an instance of MagazineViewModel BaseOutputViewModel viewM

我的视图模型都继承自一个BaseViewModel

public class MagazineViewModel : BaseOutputViewMode
{
    public string TitleOfPublication { get; set; }
}
在我的控制器中,我使用工厂方法根据输入返回正确的视图模型:

// e.g. viewModel contains an instance of MagazineViewModel 
BaseOutputViewModel viewModel = BaseOutputViewModel.GetOutputViewModel(output);
当我使用TryUpdateModel尝试绑定到我知道包含“TitleOfPublication”键的FormCollection时,它从未在我的视图模型中设置:

if (!TryUpdateModel(viewModel, form))
我认为这与DefaultModelBinder有关,DefaultModelBinder使用BaseOutputViewModel将FormCollection键绑定到—它不包含“TitleOfPublication”,而派生的MagazineViewModel则包含

我正在尝试滚动我自己的模型绑定器,以覆盖DefaultModelBinder的绑定模型行为。它的所有接线都正确,我可以在TryUpdateModel调用后直接调试到它:

 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;
    }
}
但我不确定如何使用bindingContext?需要更新哪些内容,以便告诉DefaultModelBinder使用派生视图模型属性进行绑定? 还是我完全误解了这一点

我确实尝试过重写CreateModel——很像MvcContrib中的DerivedTypeModelBinder,但我认为因为我给了binder一个模型实例来使用,所以CreateModel永远不会被调用。使用Mvc DLL上的Reflector,有一个“BindComplexModel”,仅当模型为空时才调用CreateModel:

if (model == null)
{
    model = this.CreateModel(controllerContext, bindingContext, modelType);
}
所有的指示都收到了


干杯

好的-终于弄清了真相! 实际上,我的模型绑定器没有任何问题,问题最终导致了两个没有名称/id的输入标记:

<input id="" name="" type="text">
由于没有id/名称,表单集合的键为“”,这意味着GetValue正确返回了该字段的值,并继续作为简单模型绑定

添加id/名称时,表单集合不包含“”键(在使用TryUpdateModel时,它现在是我的模型的名称)。这意味着DefaultModelBinder正确地将我的模型视为complexm,并成功地将属性绑定到我的派生类型中


干杯

好的-终于弄清了真相! 实际上,我的模型绑定器没有任何问题,问题最终导致了两个没有名称/id的输入标记:

<input id="" name="" type="text">
由于没有id/名称,表单集合的键为“”,这意味着GetValue正确返回了该字段的值,并继续作为简单模型绑定

添加id/名称时,表单集合不包含“”键(在使用TryUpdateModel时,它现在是我的模型的名称)。这意味着DefaultModelBinder正确地将我的模型视为complexm,并成功地将属性绑定到我的派生类型中

干杯