Dot-Net

DDD 和客戶端驗證

  • December 19, 2018

假設您有一個使用域模型模式、DDD 和許多其他設計模式的應用程序。假設我們有許多解決方案,如下所示:

  • 解決方案.模型
  • 解決方案.儲存庫
  • Solution.Services
  • 解決方案.介紹
  • 解決方案.UI.Web

使用者體驗層是 Solution.UI.Web,我們假設它是一個 ASP.NET WebForms 應用程序。您如何執行客戶端驗證?

有很多事情需要考慮:

首先,我們不應該訪問應用程序/數據庫伺服器來向客戶端返回任何驗證錯誤,但是我們也可以實現伺服器端驗證,但我們也需要客戶端驗證.

其次,我們不想在使用者體驗層實現驗證規則。那是因為如果您的應用程序是一個 WebApp,然後您決定創建一個 WinApp 客戶端,那麼您將不得不重新實施驗證規則 –> 維護噩夢。

一種簡單的方法是使用 ViewModel 對象(將發送到客戶端的域實體的扁平視圖)實現驗證邏輯,然後在訪問應用程序/數據庫伺服器之前驗證這些對象。

另一種方法,我見過在不同的應用程序中多次使用的方法,就是生成一組驗證錯誤消息並將該集合發送到客戶端。這很好,但有一個問題。只是驗證錯誤的簡單摘要消息是行不通的,特別是如果您有大數據輸入表單。

現在,ASP.NET MVC 框架讓生活變得更加輕鬆。您可以使用 EF + DataAnnotations,而 MVC Scaffolding 框架可以為您完成大部分工作。但如果您想創建一個 MVC 應用程序並使用 jQuery 和 JavaScript 實現您的驗證邏輯,情況就是如此。

但是,如果您需要一種更通用的方法來實現可以在不同應用程序中使用和使用的驗證框架,比如 WinForms 和 WebForms 怎麼辦?

澄清一下,我正在尋找的是一組設計模式/原則和/或技術/框架來實現可以使用您的域模型實現的驗證框架,然後在您的客戶端應用程序上強制執行。而且,我不想只返回有關違反規則或任何內容的字元串錯誤消息集合,我希望能夠在驗證失敗時更新我的數據綁定控制項(TextBox、ComboBox、DateTimePicker 等),以便使用者體驗層會更直覺(如果你願意的話)。

我在這里和那裡看到了一些實現和框架,並且我已經使用 ASP.NET MVC 客戶端驗證有一段時間了,所以我的回答與 MVC 或 JavaScript 驗證沒有任何關係。

在 DDD 中,域通常是自我驗證的。換句話說,不允許對象處於無效狀態。值對像在這裡有很大幫助。它們只是封裝了格式化規則。例如,您可以擁有保證始終格式正確的類ZipCode 。作為一個額外的責任,它可以有一個靜態方法,如ZipCode.TryParseZipCode.Validate這將採用任意字元串作為參數並進行驗證。這種方式驗證邏輯集中在一個地方。如果您的域對象可以直接從 UI 訪問,那麼您不需要在其他任何地方複製此邏輯。胖客戶端(Windows 窗體、WPF)就是這種情況。不幸的是,當 Web 客戶端需要在不往返伺服器的情況下執行驗證時,無法避免一些重複。

您應該將驗證邏輯封裝在代表您的領域知識的簡單類中。

我在我的原始痴迷部落格文章中寫過它。如果您創建此類類,您的 ASP.NET MVC 控制器可能如下所示:

public class CustomerController : Controller
{
   [HttpPost]
   public ActionResult CreateCustomer(CustomerInfo customerInfo)
   {
       Result<Email> emailResult = Email.Create(customerInfo.Email);
       Result<CustomerName> nameResult = CustomerName.Create(customerInfo.Name);

       if (emailResult.Failure)
           ModelState.AddModelError("Email", emailResult.Error);
       if (nameResult.Failure)
           ModelState.AddModelError("Name", nameResult.Error);

       if (!ModelState.IsValid)
           return View(customerInfo);

       Customer customer = new Customer(nameResult.Value, emailResult.Value);
       // Rest of the method
   }
}

無需使用註釋,因為它們本質上鼓勵您複製驗證邏輯。

比較這些程式碼範例:

引用自:https://stackoverflow.com/questions/6966288