2010-09-19 65 views
9

每次我開始處理新的ASP.NET MVC Web應用程序時,我不確定是否使用DataAnnotations驗證。有些事情感覺不對。DataAnnotations或在服務中手動驗證?

例如,假設我有一個UserService,它從AccountControllerCreate操作中通過CreateUserModel。爲確保用戶始終提供名稱,我將模型的Name屬性設置爲具有[Required]屬性。我現在是安全的,除非它有一個名字,否則模型聯編程序永遠不會給我一個CreateUserModel

我的問題是,我的UserService是我係統的一個可重用組件,它不能依賴上述層提供有效數據的事實,而且肯定也必須驗證此數據。當您考慮您可能要編寫一個完全重用UserService(並且沒有模型聯編程序爲其進行所有數據註釋驗證)的Web服務時,需要進一步突出顯示這一點。

所以我的問題是:這種情況的最佳做法是什麼?使用數據註釋進行驗證並在服務中重複驗證?僅在服務中驗證並拋出異常?兩者的混合?

我希望我的問題不是太主觀,我主要試圖建立一個關於是否將驗證移動到數據註釋最終會讓我最終咬傷我的共識。

回答

1

你是對的,你應該關閉控制器驗證並在服務層驗證。如果您願意,您仍然可以使用DataAnnotations。服務層可以使用驗證消息拋出異常,控制器可以捕獲該異常並將驗證消息添加到ModelState中。您可以通過處理控制器的OnException方法上的驗證異常來避免爲每個操作執行此操作。

1

只要邏輯是在一個地方定義的,我個人並不介意事物會被驗證兩次,這在您的情況中顯然是這樣。我對MVC的描述經驗不足,但我可以想象,從服務層拋出異常並不會給用戶體驗(UX)帶來與MVC在驗證時可以提供的一樣好的用戶體驗(UX)實例在無效的文本框旁邊顯示一條錯誤消息,當從服務層拋出異常時更難做到這一點)。當用戶體驗相同時,請僅在服務中進行驗證,否則在兩個層次都進行驗證。

6

我在服務層執行所有的驗證,使用手動驗證(如果x == y)和使用數據註釋的組合。

要在服務層中使用數據註釋,您必須使用TryValidateObject()方法手動使用Validator類。一個很好的例子可以看到here

然後,您必須將驗證錯誤從服務層傳遞到您的控制器,並讓您的控制器將每個錯誤添加到模型狀態錯誤列表中。

+1

這就是我們所做的,除了我們將IValidationDictionary傳遞給作爲ModelState包裝器實現的服務層,以便服務層能夠直接向ModelState添加錯誤,但不會依賴於ASP.NET MVC。然後控制器不需要擔心管理向ModelState添加返回的錯誤。 – 2010-11-24 21:16:50