2010-10-31 106 views
1

我有一个BaseViewModel,我的视图模型都从继承。ASP.NET模型绑定到基类型

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

在我控制我用一个工厂方法根据输入给予corret视图模型回:

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

当我使用TryUpdateModel尝试绑定到的FormCollection我知道含有“TitleOfPublication”键,它从来没有在我的视图模型设置:

if (!TryUpdateModel(viewModel, form)) 

我想这是使用BaseOutputViewModel绑定的FormCollection键与DefaultModelBinder做 - 它不包含“TitleOfPublication”,衍生的MagazineViewModel。

我想滚动我自己的模型联编程序,以覆盖DefaultModelBinder的BindModel行为。一切都在正确的有线和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使用派生的View Model属性进行绑定? 或者我完全误解了这一点!

我尝试覆盖CreateModel - 很像MvcContrib中的DerivedTypeModelBinder,但我认为,因为我给该活页夹一个模型的实例,CreateModel永远不会被调用。关于MVC DLL二手反射,那里有一个“BindComplexModel”调用CreateModel仅如果模型为null:

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

任何指针greatfully好评!

干杯

回答

1

行 - 终于到了这个底部! 事实上没有什么错我的模型绑定,这个问题最终导致回一对夫妇的输入标签是没有名字/ ID:

<input id="" name="" type="text"> 

的症结是本次测试中DefaultModelBinder:

// Simple model = int, string, etc.; determined by calling TypeConverter.CanConvertFrom(typeof(string)) 
// or by seeing if a value in the request exactly matches the name of the model we're binding. 
// Complex type = everything else. 
if (!performedFallback) { 
    ValueProviderResult vpResult = 
      bindingContext.ValueProvider.GetValue(bindingContext.ModelName); 
      if (vpResult != null) { 
       return BindSimpleModel(controllerContext, bindingContext, vpResult); 
      } 
     } 

如果没有id/name,表单集合的键值为“”,这意味着GetValue正确地返回了该字段的值,继续绑定为简单模型。

添加一个id /名称时,表单集合中不包含任何“”的键,(因为我们正在使用TryUpdateModel,所以它现在是我的模型的名称)。这意味着DefaultModelBinder正确地将我的模型作为complexm成功绑定了派生类型的属性!

干杯