2012-12-13 33 views
0

我是MVC的新手,我有一個狀態和對象持久性的概念問題,希望有人能把我的想法整理一下。ASP MVC 4管理控制器中的對象狀態

我有一個遠程web服務,它提供了管理訂單的方法。訂單由您希望的標題和行組成。行可以有額外的要求。

我有我的域對象創建(使用web服務架構中的xsd2code),web服務調用和對象序列化都工作正常。我已經構建了DAL/BLL圖層,並且都使用WinForms測試平臺應用程序前端進行了測試。

我有使用Automapper從域對象映射的視圖模型對象。作爲訂單由單個web服務方法完全與線等返回我有一個OrderViewModel如下

public class OrderViewModel 
{ 
    public OrderHeaderViewModel OrderHeader { set; get; } 
    public List<OrderLineViewModel> OrderLines { set; get; } 
    public List<OrderLineAdditionalViewModel> OrderLineAdditional { set; get; } 
    public List<OrderJustificationViewModel> OrderJustifications { set; get; } 

} 

首先我想知道如果我應與OrderViewModel分配,如果我通過這作爲模型的圖我傳遞的數據比我需要的要多得多。視圖只需要OrderHeader或OrderLines等 - 而不是整個訂單。

現在我的概念問題是在控制器和視圖和對象持久性。

我的訂單控制器有一個細節動作,它執行來自web服務的訂單的加載並將域對象映射到OrderViewModel對象。

public ActionResult Details(string orderNumber) 
    { 

     OrderViewModel viewModel = new OrderViewModel(); 
     var order = WebServiceAccess.LoadOrderByOrderNumber(orderNumber,"OBOS_WS"); 

     viewModel = AutoMapper.Mapper.Map<BusinessEntities.Order, ViewModels.OrderViewModel>(order); 

     return View(viewModel); 
    } 

但訂單/ Details.cshtml只是有頁面佈局和(使用Ajax我交換Headerview的HeaderEdit,同爲LinesView)爲頭兩個部分頁面和線路的呼叫

@{ Html.RenderPartial("DetailsHeaderViewPartial", Model);} 
@{ Html.RenderPartial("DetailsLinesViewPartial", Model);} 

此刻,我將模型傳遞到主要的詳細信息容器頁面,然後到RenderPartials,但我不認爲該模型應該傳遞到主要的詳細信息頁面,因爲它不需要它 - 模型只在DetailsHeaderViewPartial,DetailsLinesViewPartial中需要,所以我最好在這裏使用@RenderAction,然後將模型傳遞給Header /線條視圖。

但是,在ActionResult Details()中從Web服務中檢索訂單如何使控制器的ActionResult HeaderDetails()/ LineDetails()方法中可用的檢索到的OrderViewModel對象作爲返回的PartialView (...,模型)?

我是否應該使用用戶會話來存儲Order ViewModel,以便它可以在控制器中的各個操作中使用。

從這個階段開始,用戶將能夠維護訂單(添加/刪除行 - 編輯標題等)。由於保存訂單的web服務調用可能需要幾秒鐘的時間才能完成,因此我只想在用戶完成訂單時調用save方法。因此,我想在正在進行工作的某個地方堅持正在進行的訂單。用戶會話?

非常感謝您的任何建議。一旦我有了ViewModel的狀態管理的頭腦,我就可以停止閱讀一百萬篇博客文章,並且實際上編寫這些東西!

回答

1

實際上你在這裏有幾個問題,所以我會盡力解決他們所有的問題。

1)點擊視圖模型:我會說不。視圖模型表示您填充視圖所需的數據。看起來好像您將視圖模型用作域模型對象的相同容器。所以你問你是否應該放棄它,只是將域模型傳遞給視圖,而你最初的擔心是你傳遞了更多的數據,那麼你真的需要這樣做?

而不是取消視圖模型,我會重新訪問您的視圖模型上的屬性。只需使用您需要的屬性並創建映射邏輯(使用automapper或自己創建),以獲取複雜的域對象並填充視圖模型上的屬性。總結:將視圖模型構建爲視圖需要的東西,然後編寫映射邏輯來填充該視圖模型。

2)這只是一個最佳實踐的聲明,然後再詳細說明您的具體情況。

您將您的體系結構描述爲具有BLL和DAL。如果是這種情況,那麼你不應該持續從你的控制器的任何對象。控制器不應該有任何關於數據庫的知識,甚至存在,並且控制器中使用的對象應該不知道如何堅持自己。您的控制器和Web服務之間的對象應嚴格爲數據傳輸對象(DTO)。如果您不熟悉DTO的構成,那麼我強烈建議您進行一些研究並嘗試將其構建到您的解決方案中。它將幫助您在概念上查看視圖模型對象,域對象和數據傳輸對象之間的區別。

3)我不會嘗試在會話中存儲訂單對象。我將重新分析如何分解視圖中的部分視圖,以便您可以按照需要的方式使用ordersviewmodel作爲參數來調用操作。這聽起來像你不必要地將觀點分解成部分視圖。

4)您不應該關注視圖模型對象的狀態管理。您的視圖(可以由許多局部視圖組成)根據視圖模型提供的屬性填充。用戶可以使用您開發的用戶界面進行更改。由於您表達了只有在完成所有更改以優化對Web服務的調用後才保存的願望,您只需單擊提交即可重新填充視圖模型的字段。現在,您有一個表示用戶更改的orderviewmodel的「狀態」。您可以在轉換回DTO(如果您執行上述操作)或將其映射到域對象後將此對象發送到Web服務。

1最後的筆記。您正在使用automapper將您的域映射到視圖模型。我假設你的視圖模型太複雜了,並且包含了你不需要的東西,因爲你構建了視圖模型來模擬域對象,以便automapper可以通過命名約定進行映射。 Automapper具有用於執行超出標準相同名稱屬性的複雜(自定義)映射的api。不要讓automapper限制你以某種方式構建視圖模型。

希望這有助於

+0

感謝您的回覆。關於視圖模型,我不打算完全放棄它 - 只是將它從OrderViewModel容器(包括標題和行)拆分爲獨立的視圖模型 - 因此我可以將OrderHeaderViewModel傳遞給部分標題,而不是傳遞整個訂單模型。 部分視圖的原因是爲了在單個頁面中顯示順序,但是允許通過使用Ajax切換視圖替換具有編輯視圖的部分視圖來編輯標題或行。因此,加載整個訂單,然後使用partials繪製。 – MartinS