簡體   English   中英

Web應用程序驗證設計決策

[英]web application validation design decisions

我的項目中有這個結構。
EmployeeController層調用EmployeeApi層,而EmployeeApi層調用EmployeeBusinessLogic(bll)層。

控制器與EmployeeModel一起使用,而bll與EmployeeEntity(nhibernate)一起使用。
API層將模型從模型轉換為實體,並賦予bll。
驗證可在控制器(MVC)上進行,並到達已驗證的BLL。
我是否需要在bll上再次驗證實體? 因為如果有人開發並重新使用我的bll,他可能會向其發送未經驗證的數據。 我應該兩次驗證數據嗎? 在BLL和控制器上?
對我來說,這看起來像是重復,因為模型與實體相似度為80%。
解決方法是什么? 謝謝

我將始終在BLL上進行驗證,因為它是您系統的核心。 由於系統將通過可能無法控制或由具有不同需求的應用程序使用的服務公開,因此這是一種確保數據無論來自何方都有效的方法。

例如,考慮以下示例:

MVC應用| 內部cmd工具| 第三方申請

服務層

業務層

您首先需要在核心業務和服務層之上創建一個MVC應用程序。 然后有人認為創建一個內部命令行工具是一個好主意,該工具可以在您的應用程序核心上執行某些操作。 如果您不在業務層上進行驗證,那么您將需要重復由MVC應用程序完成的驗證。 您可以忍受這一點,但是如果您將服務公開給第三方,則服務層的使用者甚至可能無法控制。 因此,最終,完全信任您的數據的唯一方法是在持久化之前在業務層進行驗證。

同樣取決於應用程序,在其他一些層上添加驗證(例如在ASP MVC應用程序上的控制器或客戶端驗證)也很有用。 這樣,操作將盡早失敗,並盡快將錯誤通知用戶。

例如,在MVC應用程序中,簡單的驗證將使用jquery驗證和MVC非侵入式驗證在客戶端進行,因此當發現錯誤時,它甚至不需要將數據發送回服務器並等待響應。 您還需要在控制器操作中執行另一個驗證步驟,在此將驗證您的視圖模型。 如果在控制器上發現任何錯誤,則會將其添加到ModelState中,並且通常會將用戶重定向到顯示錯誤並可​​以采取措施的屏幕。 最終,您的應用程序核心將驗證傳入的數據,發現的任何錯誤將被發送回堆棧中。

正如您所說的,您似乎將重復大量的驗證代碼,但是有一些方法可以最小化這種影響。 在使用ASP MVC時,一個示例可能是將數據注釋和驗證庫混合在一起:

  • 您可以在模型和業務對象上使用數據注釋,以進行最簡單的驗證,例如要求或正則表達式。 您還可以開發自己的數據注釋驗證屬性。

     public class EmployeeModel { [Required] public string Name {get; set;} ... } public class EmployeeEntity: BaseEntity { [Required] public string Name {get; set;} ... } 
  • 對於您的業務層,創建一個僅包含數據注釋屬性的基本驗證器。 (類似於此處描述的方法: http : //odetocode.com/blogs/scott/archive/2011/06/29/manual-validation-with-data-annotations.aspx

     public class BaseValidator<T> where T: BaseEntity { public virtual ValidationResult Validate(T entity) { ... validate data annotations here ... } } 
  • 這將為您提供客戶端,控制器和業務層的相同基本規則集,主要與用戶輸入有關。

  • 對於任何具有更復雜的驗證邏輯的實體,請從業務層中僅考慮數據注釋屬性的派生特定驗證器。 為該實體類型添加特定且更復雜的驗證邏輯。

     public class EmployeeValidator: BaseValidator<EmployeeEntity> { public override ValidationResult Validate(EmployeeEntity entity) { base.Validate(entity); ... perform complex BLL calculations ... } } 
  • 最后,在控制器層中添加一些代碼,這些代碼將從業務層引起的任何驗證錯誤添加到ModelState中。 例如,您可以在基本控制器類上添加這樣的方法:

     public void AddValidationsToModelState(ValidationResult validationResult) { foreach(var error in validationResult.Errors) { ModelState.AddModelError(error.property, error.message); } } 

最后,您將獲得一個公用的數據注釋屬性共享庫,以及業務層中特定的驗證過程。 希望能幫助到你!

就個人而言,我永遠不會相信跨越服務邊界的數據。 如果您的業務邏輯層旨在共享,那么您應該再次進行驗證。 是的,它是重復的,但是我在這里看不到任何其他選擇。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM