根据 DTO、实体模型或其他东西验证服务层中的数据?
Posted
技术标签:
【中文标题】根据 DTO、实体模型或其他东西验证服务层中的数据?【英文标题】:Validating data in the service layer against DTOs, Entity Models, or something else? 【发布时间】:2018-01-05 01:18:37 【问题描述】:我正在开发一个 ASP.NET MVC 项目。在项目中,我有一个接受 DTO 进行 CRUD 操作的服务层。当我需要验证业务逻辑时,验证器应该完全接受 DTO、实体模型还是其他东西?
例如:
public class ProductService: IProductService
public ValidationResult CreateProduct(ProductDTO productDto)
//call productValidator.Validate(productDto) on the DTO here?
Product productEntityModel = mapper.Map<Product>(productDto);
//or, call productValidator.Validate(productEntityModel) on the Entity model here?
if(validationResult.Valid)
_dbContext.Products.Add(productEntityModel);
_dbContext.SaveChanges();
return validationResult
一些想法:
我在网上看到一些关于创建 POCO 的讨论,该 POCO 可以具有验证逻辑(而不是使用验证服务),甚至可以在其中包含其他业务逻辑。这是有道理的,但它又是一种必须管理和维护的产品的“代表”。 根据 DTO 进行验证可能看起来更合理一些,因为那是调用者正在发送到服务?感谢您的帮助!
【问题讨论】:
我使用 DTO 方法并有一个问题。当您的方法签名为List<History> ListHistory(int userId, string specialString)
时,您将如何返回验证错误?
【参考方案1】:
当我需要验证业务逻辑时,验证器是否接受 DTO、实体模型,还是完全其他的东西?
通常,我们在ViewModel
类中使用DataAnnotations
执行验证,以便我们可以返回用户友好的ModelError
。例如,
public class LoginViewModel
[Display(Name = "Username")]
[Required(ErrorMessage = "Please enter your username.")]
public string UserName get; set;
public async Task<ActionResult> Login(LoginModel model, string returnUrl)
if (ModelState.IsValid)
...
ModelState.AddModelError("", "User is not authorized!");
...
虽然您可以验证 ProductService
内部的一些业务逻辑,但您不能返回 MVC ModelError
,因为服务/存储库层不应依赖于 ASP.NET MVC(或任何 UI 组件)。
Service/Repository Layer 中的大部分错误都是意外错误,而不是用户错误。我们通常在 NLog 或 Log4Net 中记录这些错误,并将用户重定向到自定义错误页面。
【讨论】:
我应该指定需要数据库访问的深层/复杂逻辑,而不是像必填字段这样的简单验证。例如,验证数据库中不存在另一个同名产品。 我个人喜欢将业务逻辑保留在操作方法中。我喜欢我的服务/存储库层尽可能干净。看看这个基于 ASP.NET MVC 的最好的开源购物车之一 - Create Action Method 和 InsertCustomer method 在 Repository/Service 类中。 啊,我个人喜欢 Service 或 Core 项目中的业务逻辑,而不是 web/presentation 项目。如果需要添加另一个表示层或需要使用单独的 API,我不想重复逻辑。 没有正确或错误的答案。看来您已经准备好做出决定了;我会说去吧。以上是关于根据 DTO、实体模型或其他东西验证服务层中的数据?的主要内容,如果未能解决你的问题,请参考以下文章