2011-01-28 43 views
6

對於我的每個業務實體,我都有相應的視圖模型。ASP.NET MVC:如何讓我的業務規則驗證泡泡到表示層?

我有一個通用的CRUD控制器,它的工作原理是這樣的:

[HttpPost] 
    public virtual ActionResult Create(TViewModel model, int? id) 
    { 
     // Validate input 
     if (!ModelState.IsValid) 
      return Json(Failure(createView, model.SelectLists(repository))); 

     // Prepare Model 
     var entity = new TModel(); 

     // Add to repository 
     UpdateModel(entity); 
     repository.Add(entity); 
     repository.Save(); 
     return Json(CreateSuccess(entity)); 
    } 

我在我的視圖模型屬性使用數據註釋,這對於簡單的輸入驗證的偉大工程。

現在我有一個情況,我想確保重複記錄不是偶然創建的。

我的第一個直覺就是把這個邏輯放到版本庫的Add方法中。這個實現很簡單,但是如何獲取存儲庫來添加模型狀態錯誤並向用戶返回一些有用的信息?我覺得有必要有一個解決方案,但我沒有太多的運氣搜索。

感謝您的幫助!

回答

3

我會使用例外。

  • 如果一個enity加倍,則將您的自定義應用程序異常拋出在Add方法中。
  • 將Add方法包裝在try塊中以在Create方法中捕獲此特定異常。
  • 在catch塊

    try 
    { 
        repository.Add(entity); 
    } 
    catch(MyRepositoryException ex) 
    { 
        ViewData.ModelState.AddModelError(ex.Key, ex.Value.ToString(), ex.Message) 
    } 
    
    if (!ModelState.IsValid) 
          return Json(Failure(createView, model.SelectLists(repository))); 
    
+0

看起來像我在下面發佈的基本的書呆子晚餐概念的一個很好的總結。正如我在我的回答中所述,我不喜歡使用異常的想法,而是主動在實體(或本例中的存儲庫)上調用Validate()方法。謝謝! – 2011-01-28 03:19:21

1

我討厭回答我的問題,添加基於異常數據的模型狀態錯誤,但我覺得我碰到我一直在尋找而尋找答案跌跌撞撞別的東西:

http://nerddinnerbook.s3.amazonaws.com/Part3.htm

看起來好像是時候了背到基礎評論!我應該考慮回顧我的第一篇教程,因爲當我剛開始時,我沒有辦法吸收所有的東西。

if (ModelState.IsValid) { 

    try { 
     dinner.HostedBy = "SomeUser"; 

     dinnerRepository.Add(dinner); 
     dinnerRepository.Save(); 

     return RedirectToAction("Details", new{id=dinner.DinnerID}); 
    } 
    catch { 
     ModelState.AddModelErrors(dinner.GetRuleViolations()); 
    } 
} 

有關實現該返回與屬性名稱和錯誤消息字符串將被添加到控制器的ModelState中,這使得這種驗證出錯的域模型驗證教程會談3部分我不知道我是否喜歡爲違反商業規則提出例外的想法,但基本模式對我的項目來說會很有效。希望這可以幫助別人!

+0

我在catch塊中編輯了代碼:它應該是「ModelState.AddModelErrors ...」。對於想知道爲什麼ModelState中沒有「AddModelErrors」方法的人來說,它是一種擴展方法。 http://forums.asp.net/t/1409804.aspx/1 – Rohit 2013-08-06 16:31:03

1

您的方法的替代方案是使用ModelStateWrapper實現IValidationDictionary的想法。它基本上解耦了modelState,但仍然讓您的存儲庫/服務與錯誤字典進行交互。這種方式的錯誤處理都是通過接口完成的,不需要引用任何MVC特定的數據對象。

有好就可以了書面記錄在這裏:http://www.asp.net/mvc/tutorials/validating-with-a-service-layer-cs,但其基本思想是:

public MyController() 
{ 
    repository = new MyRepository(new ModelStateWrapper(this.ModelState)); 
} 

2)地址:

1)控制器的初始化過程中通過你的ModelStateWrapper的實例來存儲庫錯誤是你的資料庫裏面:

_validatonDictionary.AddError("Name", "Name is required."); 

3)處理錯誤就像你通常會在你的控制器:

if (!repository.Save()) 
    return View();