2011-09-29 48 views
7

有沒有一種方法可以調用單個對象的模型聯編程序?MVC直接在單個對象上調用模型聯編程序

我不希望/需要自定義模型粘合劑 - 我只想做這樣的事情:

MyViewModel1 vModel1 = new MyViewModel1(); 
InvokeModelBinder(vModel1); 

MyViewModel2 vModel2= new MyViewModel2(); 
InvokeModelBinder(vModel2); 

當我做,既vModel1和vModel2的屬性已綁定到傳入請求中有什麼。由於我們的控制器/操作正在編寫的方式,我不一定希望在操作方法的輸入列表中列出vModel1和vModel2(因爲最終將成爲視圖模型的可能長列表,以便可選地綁定)。

回答

2

這是錯誤的在許多層面上恕我直言:

  1. 這不是ASP.NET MVC是如何設計工作。
  2. 你的行爲沒有定義他們期望的數據的明確合同。
  3. 你從中得到什麼?聞起來像不好的設計。

模型綁定是由反射驅動的。在調用動作之前,它將反映方法參數列表,並且爲每個對象及其屬性調用模型聯編程序,以便爲來自各個值提供程序(表單POST值提供程序,url參數等)的每個屬性查找值。在模型綁定過程中,ModelState驗證也完成。

因此,通過不使用默認的ASP.NET MVC來做到這一點,你正在失去所有這一切。

即使你是手動得到一個模型綁定這樣的保持:

IModelBinder modelBinder = ModelBinders.Binders.GetBinder(typeof(MyObject)); 
MyObject myObject = (MyObject) modelBinder.BindModel(this.ControllerContext, ** ModelBindingContext HERE**); 

你可以看到,你需要一個initalize ModelBindingContext,一些ASP.NET MVC會做內部基於當前它反映的財產。

protected virtual object GetParameterValue(ControllerContext controllerContext, ParameterDescriptor parameterDescriptor) { 
// collect all of the necessary binding properties 
Type parameterType = parameterDescriptor.ParameterType; 
IModelBinder binder = GetModelBinder(parameterDescriptor); 
IDictionary<string, ValueProviderResult> valueProvider = controllerContext.Controller.ValueProvider; 
string parameterName = parameterDescriptor.BindingInfo.Prefix ?? parameterDescriptor.ParameterName; 
Predicate<string> propertyFilter = GetPropertyFilter(parameterDescriptor); 

// finally, call into the binder 
ModelBindingContext bindingContext = new ModelBindingContext() { 
    FallbackToEmptyPrefix = (parameterDescriptor.BindingInfo.Prefix == null), // only fall back if prefix not specified 
    ModelName = parameterName, 
    ModelState = controllerContext.Controller.ViewData.ModelState, 
    ModelType = parameterType, 
    PropertyFilter = propertyFilter, 
    ValueProvider = valueProvider 
}; 
object result = binder.BindModel(controllerContext, bindingContext); 
return result; 

}

+0

'你從中得到什麼?聞起來像糟糕的設計。「看起來像一個糟糕的設計綁定到多個模型類型,但它有一個很好的性能使用。你可以先注入所有被初始化的東西,然後做一個警戒子句並儘早返回,而不是使用已經設置好的注入對象。或者,在守衛子句之後,一旦確定要使用某個對象,請使用'UpdateModel'來解析依賴關係。這很麻煩,但如果你必須進行設計交易以達到性能,這是一種可能性。 – StuperUser

8

使用Controller.UpdateModel

MyViewModel1 vModel1 = new MyViewModel1(); 
UpdateModel(vModel1); 

更新

注意如果ModelState在控制器具有驗證錯誤下面是從ASP.NET MVC源代碼剪斷(與傳入的模型相關),UpdateModel(使用任何模型)拋出excetion,儘管Upd ateModel成功並更新vModel1。因此,ModelState中的錯誤應該被刪除,或者將UpdateModel放在try/catch中,並且忽略例外

+1

FWIW,這就是爲什麼我很高興找到這個魔法。我正在實施一個「嚮導」框架(即通過「下一頁」和「上一頁」按鈕將單個長表單拆分爲多個小表單的方式)。我希望每個單獨的頁面都POST回到通用控制器操作,但每個頁面都有其自己的強類型視圖模型,並帶有驗證屬性。由於我有一個共同的控制器操作,我不知道要綁定哪個視圖模型,直到我查看哪個頁面發回給我。 –

相關問題