2010-10-31 98 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成功綁定了派生類型的屬性!

乾杯