我正在構建一個頁面來編輯各種產品類型。每種產品類型都有一個從ProductVM繼承的視圖模型(TentProductVM,BootProductVM)。我的MVC2視圖檢查模型類型並根據需要添加字段。例如,如果模型屬於BootProductVM類型,我會調用Html.TextBoxFor爲引導腳的尺寸添加一個字段。頁面顯示正常。MVC2使用子類的帖子
問題是帖子。我已經聲明瞭一個函數(在VB中),如下所示:
<HttpPost()>Function Edit(byval prod as ProductVM) As ActionResult
當然,這個函數只接收來自基類ProductVM的表單數據。於是我又增加了一個功能,每個產品類型:
<HttpPost()>Function EditTent(byval prod as TentProductVM) As ActionResult
<HttpPost()>Function EditBoot(byval prod as BootProductVM) As ActionResult
,並指出查看到相應的崗位職能:
Using Html.BeginForm("Edit" & Model.ObjectTypeName, "Catalog")
然而,當EditTent或EditBoot被調用,督促參數僅包含數據來自基類。所有在子類視圖模型中聲明的字段都保留默認值。
我在做什麼錯?還是有更好的方法? (顯而易見的解決方案是多頁,但由於ProductVM具有相對於子類衆多領域,我寧願不要。)
多次試驗之後,我決定不使用這種方法。首先,我無法使用FormCollection類型的Action參數來使其工作。其次,如果我使用局部視圖,我放棄的顯而易見的解決方案是有吸引力的。部分視圖具有與基類(ProductVM)相關的所有字段,僅保留常規視圖中與派生類(TentProductVM,BootProductVM)關聯的字段。
感覺就像我在與MVC自動魔法戰鬥,這是從來沒有正確的做法。
令我驚訝,我改變了參數的名稱爲「模型」,它被設置爲空! – Adventure 2011-05-03 18:04:07
問題可能是我的視圖繼承了_System.Web.Mvc.ViewPage(MyNamespace.ProductVM)_但我的post函數參數是_BootProductVM_的子類? (如果編輯各種產品類型共享一個頁面,這當然是不可避免的。) – Adventure 2011-05-03 18:07:36
這樣做。如果你要有一個共享的視圖,使用這種通用的ViewModel,你將不得不在你的操作方法中接受一個「ProductVM」。然後,將其映射到您的控制器方法內的實際數據模型。你也可以創建一個自定義的ModelBinder,但我認爲第一個選項是最簡單的。 – JasonOffutt 2011-05-03 19:52:10