2009-09-21 55 views
4

假設我想允許在頁面上選擇我們的實體(從下拉列表等),讓我們說產品。因此,我可能會收到這樣的:我的自定義ASP.NET MVC實體綁定:這是一個很好的解決方案嗎?

public ActionResult SelectedAction(Guid productId) 
{ 
} 

不過,我想用模型聯電,所以不是我寫的模型綁定從儲備庫中獲得我的產品,轉而使用

public ActionResult SelectedAction(Product product) 
{ 
    if (ModelState.IsValid) {} else {} 
} 

我的模型綁定如果產品無效,則將模型狀態設置爲false。 現在,正在使用這種方法的問題:

  1. 這並不總是易於使用強類型的方法,如Html.ActionLink(C => c.SelectedAction(ID)),因爲我們需要傳遞的產品,而不是ID。
  2. 無論如何,使用實體作爲控制器參數並不好。
  3. 如果模型狀態無效,並且我想重定向回來並顯示錯誤,我無法保留所選產品!因爲綁定的產品沒有設置,我的ID不存在。我想要做RedirectToAction(c => c.Redisplay(product)),但當然這是不可能的。

現在,似乎我回來使用「Guid productId」作爲參數...但是,有一個解決方案,我想提出和討論。

public class EntityViewModel<T> where T : BaseEntity 
    { 
     public EntityViewModel(Guid id) 
     { 
     this.Id = id; 
     } 

     public static implicit operator EntityViewModel<T>(T entity) 
     { 
     return new EntityViewModel<T>(entity.Id); 
     } 

     public override string ToString() 
     { 
     return Id.ToString(); 
     } 

     public Guid Id { get; set; } 
     public T Instance { get; set; } 
    } 

現在,如果我用

public ActionResult SelectedAction(EntityViewModel<Product> product) 
{ 
    if (ModelState.IsValid) {} else {} 
} 

所有的問題都解決了:

  1. 我只能與ID傳遞EntityViewModel設置,如果我只有編號。
  2. 我不使用實體作爲參數。而且,I 可以使用EntityViewModel作爲另一個ViewModel中的屬性。
  3. 我可以將EntityViewModel傳遞迴RedirectToController,它將保持其Id值,這將隨着驗證消息(感謝MVCContrib和ModelStateToTempData/PassParametersDuringRedirect)重新顯示給用戶 。

模型聯編程序將從存儲庫中獲取實例,並將設置模型狀態錯誤,如「在數據庫中未找到」等。我可以使用ActionLink(c => c.Action(Model.MyProductViewModelProperty))。

問題是,這裏有什麼缺點嗎?我看不出有什麼不好,但我仍然對MVC不熟悉,可能會錯過一些重要的事情。也許有更好的和批准的方式?也許這就是爲什麼每個人都使用實體ID作爲輸入參數和屬性?

+1

+1有趣的方法... – 2009-09-21 09:39:09

+1

+1這是一個體面的方法。我喜歡。 – grenade 2009-09-21 09:51:32

回答

2

總體看起來像一個良好的appoach給我...

作爲替代方案,你可以使用POCO爲你的視圖模型,然後我想所有3個問題就自動解決。您是否看到過允許實體到DTO方法的Automapper項目?通過將ViewModel從EntityModel中分離出來,這會給你更多的靈活性,但這取決於你正在構建的應用程序的複雜性。

MVC的ViewDataExtensions也可能是有用的,而不是創建自定義的容器中,作爲你們的人數提起舉辦各種視圖模型對象2.

MVCContrib的ModelStateToTempData應該對任何可序列化對象的工作(必須是可序列化的任何進程外SessionState的供應商例如SQL,Velocity等),所以即使沒有包裝你的實體類,你也可以使用它嗎?

+0

我的實體是POCO。 1)的問題是業務規則並不總是允許新的實體(id),以便由ActionLink構造Id,並且3)如果輸入/選擇的id無效(不在db中),我將爲null實體從庫中,因此null是通過ModelStateToTempData傳遞的內容。所以我不明白AutoMapper如何在DTO中沒有Id和Entity的情況下提供幫助。請記住,目標是讓實體已從存儲庫中檢索,如果失敗,仍然有Id。至於ViewDataExtensions,我不太喜歡這種方法。 – queen3 2009-09-22 16:55:11

+0

我在考慮使用演示模型,而不是直接綁定到業務對象:http://odetocode.com/Blogs/scott/archive/2009/04/05/12740.aspx,但我想這是一個不同的架構,而不是直接替代您的想法。 對於ModelStateToTempData問題,您可以使用空對象模式,但將請求的ID包括爲屬性,而不是返回c#空值。 – 2009-09-22 20:18:50

相關問題