2017-04-11 76 views
9

我有一個asp.net核心Web API結構如下:如何在.net Core web API中構建數據驗證?

View Layer: API endpoints 
    | 
    V 
Controller Layer: Controller classes implementing endpoints 
    | 
    V 
Business Logic Layer: Services 
    | 
    V 
Data Access Layer: Proxy classes to our backend 

有一系列的都遵循這種結構的端點。大多數API純粹是對後端的數據查詢,但一些API也允許調用客戶端提交數據。

我正在努力尋找一種乾淨的方式來鞏固必須在提交的數據上發生的各種驗證。

我最初的意圖是Controller層非常簡單,並將所有真正的「工作」(包括驗證)交給服務層,而Controller層只負責發送適當的HTTP響應。然而,我的問題是,在服務完成所有實際工作之後,如何最好地與控制器進行溝通,以便返回應該返回的內容。

我可以使用數據註釋來捕獲一些基本的驗證,並且在大多數情況下,對於數據驗證而言實際上可能已經足夠了。但是,這並不像覆蓋更復雜的驗證,或者失敗的服務/數據訪問層WRT讀/寫等其他問題

我已經反覆考慮的一些想法:

  • 充分利用服務層意識到IActionResult接口並使其負責確定要返回給調用客戶端的內容。然後這混合了Controller和Service層,但使Controller層非常精簡。

  • 爲各種服務調用創建各種「OperationResults」對象,它們將封裝由Controller層解釋的任何錯誤消息,異常,錯誤代碼等,以確定將什麼http響應發送回客戶端。這是一個更清晰的分離,因爲服務層根本不會與http代碼混合,但會將控制器類轉換爲一大組交換機來確定要發回的內容。

  • 根據在控制器與服務級別捕獲的內容進行驗證。例如,控制器傳遞一個空對象進行保存應該明確地拒絕它並返回BadRequest(),但當服務層也有自己的原因希望檢查時,在那裏添加檢查似乎是多餘的。

我承認在一般有點新的.NET網絡API和.NET的核心,所以如果有可用的一些明顯的功能我不接受的優勢,我很想知道。

任何意見,將不勝感激,謝謝。

+0

異常應儘快提出,根據您的模型,您發現有問題,因此如果它可能被控制器捕獲,請勿將其留給業務模型。如果某些功能是必要的但是是多餘的,那麼它會響應繼承。 – Xaqron

+3

簡短的回答是把它放在你的控制器動作中。無論什麼架構,控制器都是第一道防線。服務層不應該有任何形式的驗證。實際上你的服務層甚至不應該知道IActionResult是什麼。查看[FluentValidation](https://github.com/JeremySkinner/FluentValidation)。它是一個成熟,穩定且廣受歡迎的驗證庫。如果你縮小你的問題的範圍,我會很高興舉出一些例子,但目前的形式有點寬泛。 – trevorc

回答

5

主要思想是正確的 - 您需要在代碼中分離正常流和錯誤流。其中一種主要方法是使用.NET Exceptions來指示正常流程是不可能的。

  • 對於輸入驗證使用ActionFilter。您可以爲所有控制器設置全局過濾器或定義特定的每個操作。請參閱文檔中的Filters部分。

  • 在控制器操作執行期間,應儘快引發異常並停止進一步的執行。是的,異常可以在任何級別上提出(服務/業務層,DA層等)。

如何處理引發的異常?

使用ASP.NET Core提供的錯誤處理方法(如ExceptionHandler或Exception Filters),您可以分析異常並相應地生成適當/不同的響應。例如 查看相關SO Error handling in ASP.NET Core 1.0 Web API (Sending ex.Message to the client)問題。文檔中還有error-handling section

+0

如果我需要本地化的錯誤消息,我該怎麼辦?如何處理異常類型,我們是否需要爲特定的驗證規則創建特定的異常? –

相關問題