2011-10-12 72 views
3

我一直在閱讀的大多數MVC教程似乎爲每個模型創建4個View對象。例如,如果我的模型是「Foo」,則似乎有4個.cshtml文件:Foo/Create,Foo/Delete,Foo/Details和Foo/Edit。使用VisualStudio「腳手架」助手也是如此。爲每個Model CRUD操作分開ASP.NET MVC View對象?

這真的被認爲是MVC的最佳做法?有4個80-90%相同的課程感覺不對。當我爲Foo添加一個新字段時,我需要編輯所有4個.cshtml文件。這種雙維護(四維護?)只是讓我的OO皮膚爬行。

請告訴我:有沒有一個預期/接受的最佳做法,處理這種不同?或者,如果這真的被接受爲最佳實踐,請告訴我爲什麼四重維持不應讓我感到不安。我是一個相當熟練的ASP.NET/c#/ OO設計老手,但對MVC來說很新穎;所以,如果這是一個noob問題,請道歉。在此先感謝您的幫助!

編輯:感謝所有答覆!我標記了最徹底的答案,但提出了所有有用的建議。

回答

5

你可能兩個到四個不同的視圖之間需要:

  • 列表(查看很多事情)
  • 視圖(用於查看一個單一的東西可能沒有必要,如果是OK使用。編輯爲查看,或者如果列表有空間來顯示所有屬性)
  • 創建
  • 編輯(可以是相同的創建,如果你的代碼巧妙地)

因此,如果您的模型沒有太多的屬性將它們全部顯示在表格中,並且如果您沒有靜態的,不可編輯的視圖來檢查,您可以使用List和編輯並取消其他兩個。

但是,如果更新模型,這並不能解決雙重(或三重)維護問題。還有其他的魔術;)

在ASP.NET MVC 3中,有HtmlHelper的擴展,讓你做Html.DisplayForModel()Html.EditorForModel()。這些使用預定義的模板將自己嵌套到對象中,並繪製所有公共屬性的顯示/編輯字段。如果你傳遞DisplayForModel一個IEnumerable<Foo>,它會創建一個列標頭是Foo(使用DisplayName屬性信息,如果您提供的話)和每一行代表一個Foo實例的屬性名稱的表。如果您給EditorForModel a Foo,它將爲Foo上的每個公共財產創建一個<label><input>

所有這些強大的擴展方法所用的模板,可以由您進行更換,如果你不愉快的默認值。這可以對Foo的水平,在這種情況下,你可以回到你的雙維護的情況下,或者在較低水平(如stringDateTime),以影響與模板生成的所有編輯/顯示領域做到無論。

有關具體的工作,google "ASP.NET MVC 3 editor templates"讀一對夫婦教程的詳細信息。他們會比我更好地解釋細節。

+0

生成的表單使用Html.EditorFor(),但EditorForModel()對我來說是新的 - 我一定會給它看看。總的來說,聽起來像生成的CRUD-View代碼對於RAD和概念證明來說很好。但對於長期可維護的代碼,有更好的方法來實現我的CRUD操作。感謝您的深入響應! – mikemanne

0

我傾向於創建一個對象的CRUD OPS以下:

  • 索引
  • _form (局部的)
  • 更新
  • 刪除
  • 視圖

由於新版本和更新版本之間共享同樣的形式,兩者之間的差異很小。這真的取決於你想要變化的程度。

至於刪除,這是可選的。我喜歡在JavaScript禁用的情況下查看視圖。

編輯: 你提到的視圖模型和上面貼一個長期的,令人費解(無犯罪)的傢伙VM代碼示例。個人而言,我討厭寫入基本鏡像域對象的類,它們只用於「移動」數據。我討厭虛擬機。我討厭DTO。我討厭所有讓我不得不寫更多代碼的東西。

我想我已經喝了其他框架(鐵軌,sinatra,node.js)的coolaid到我不能忍受折騰DRY的想法。

我個人說,跳過這個。

EDIT2我忘記名單..

+2

如果你冷靜下來,有禮貌地說爲什麼。 – Chance

+0

@mikemanne正確,所以你基本上創建了一個包含你需要的模型的表單(包括一個隱藏的id)並將它傳遞給你期望的模型。請記住,您需要在最初的新請求中創建模型的新實例。隨後的請求(以及更新請求)應該有一個實例來操作。 – Chance

+0

所以你的「新」和「更新」都調用RenderPartial來包含_form中定義的常用表單字段。這開始感覺像更熟悉的領域。 :)在過去,我也使用了「細節」的相同形式,所有字段都設置爲只讀。 – mikemanne

0

,當你執行你可以使用完全相同的觀點[HTTPGET。假設您將適當的ViewModel傳遞給此視圖,則無論您是加載創建,更新還是刪除操作,每次都會填充適當的數據。

當您嘗試將該數據發佈到特定操作時,問題就會變得明顯。自然視圖應該只有一種形式,它將用於發佈數據。當你聲明這個表單時,你可以指定哪個行爲用於Post。

有3種不同的提交按鈕以這種形式不會有所作爲,因爲他們都將發佈相同的形式以同樣的動作。

你可以做OnClick事件這些按鈕一些JavaScript的調整來改變行動以數據發佈,但這種明確不會是最好的做法。

Buttom line:對於每個CRUD操作有4種不同的視圖是MVC的最佳實踐。

+0

我的理解是有不同的重載Html.BeginForm(),這將允許我動態指定要執行的操作,在我呈現該表單時。因此,我不認爲我需要4個不同的View類來生成具有4種不同動作的表單。 – mikemanne

+0

正確。現在你提到它了,我給了它更多的想法......你可以將Action名稱傳遞給ViewBag中的視圖,並將該值賦給BeginForm聲明中的Action參數。 BeginForm的任何重載都將允許您執行此操作。 – Dmitry

1

ASP.NET MVC爲您創建的視圖不一定需要是您在生產中使用的視圖。我發現那些只是在開發快速原型或測試數據庫CRUD操作時很方便。隨意創建您想要處理操作的任何視圖。

我通常只有1或2個視圖來處理基本操作,而不是使用生成的內置視圖。例如,1個用於添加,編輯或細節的視圖,1個用於顯示對象列表的視圖。

+0

謝謝Tim!我懷疑生成的4分離視圖類可能不是最好的現實世界方法。 – mikemanne

1

這一切都取決於您的應用程序。

如果您有單個項目,則不需要列表視圖。如果你不能編輯它,那麼你不需要編輯視圖。創建和編輯通常可以是相同的視圖,除非你需要在一個特定的事情中做,而不是另一個。

換句話說,根據需要使用盡可能多的視圖。這裏沒有硬性規定。腳手架只是在那裏幫助你的方式。使用腳手架的許多類型的應用程序都可以正常工作,並且不需要高級的HTML或Javascript。

爲什麼你想要多個視圖?好吧,我們來看看顯示和編輯功能。您可以創建一個視圖,在該視圖中使用if語句來確定視圖的編輯模式,但這會使視圖邏輯複雜化,視圖應該儘可能簡單。

創建獨立視圖的原因在於,它比其中包含大量條件邏輯的龐大視圖更容易維護。