C# 根据DTO、实体模型或其他内容验证服务层中的数据?

C# 根据DTO、实体模型或其他内容验证服务层中的数据?,c#,asp.net-mvc,validation,dto,service-layer,C#,Asp.net Mvc,Validation,Dto,Service Layer,我正在从事一个ASP.NETMVC项目。在这个项目中,我有一个服务层,它接受用于CRUD操作的DTO。当我需要验证业务逻辑时,验证器应该完全接受DTO、实体模型还是其他东西 例如: public class ProductService: IProductService { public ValidationResult CreateProduct(ProductDTO productDto) { //call productValidator.Validate(p

我正在从事一个ASP.NETMVC项目。在这个项目中,我有一个服务层,它接受用于CRUD操作的DTO。当我需要验证业务逻辑时,验证器应该完全接受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
    }
}
公共类ProductService:IPProductService
{
公共验证结果CreateProduct(ProductDTO ProductDTO)
{
//在这里对DTO调用productValidator.Validate(productDto)?
ProductProductEntityModel=mapper.Map(productDto);
//或者,在这里对实体模型调用productValidator.Validate(productEntityModel)?
if(validationResult.Valid)
{
_dbContext.Products.Add(productEntityModel);
_dbContext.SaveChanges();
}
返回validationResult
}
}
一些想法:

  • 我在网上看到过一些关于创建一个POCO的讨论,它可以包含验证逻辑(而不是使用验证服务)甚至其他业务逻辑。这是有道理的,但它是必须管理和维护的产品的又一个“代表”
  • 根据DTO进行验证似乎更合理一些,因为调用方正在向服务发送数据
谢谢你的帮助

当我需要验证业务逻辑时,验证器是否应该接受 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!");
   }
   ...
}
公共类LoginViewModel
{
[显示(Name=“Username”)]
[必需(ErrorMessage=“请输入您的用户名。”)]
公共字符串用户名{get;set;}
}
公共异步任务登录(LoginModel模型,字符串返回URL)
{
if(ModelState.IsValid)
{
...
AddModelError(“,“用户未授权!”);
}
...
}
尽管可以验证
ProductService
中的某些业务逻辑,但不能返回MVC
ModelError
,因为服务/存储库层不应依赖于ASP.NET MVC(或任何UI组件)


服务/存储库层中的大多数错误都是意外错误,而不是用户错误。我们通常将这些错误记录在NLog或Log4Net中,并将用户重定向到自定义错误页面

我应该指定需要数据库访问的深层/复杂逻辑,而不是像必填字段那样的简单验证。例如,验证数据库中不存在另一个同名产品。我个人喜欢将业务逻辑保留在action方法中。我喜欢我的服务/存储库层尽可能干净。看看这一款基于ASP.NET MVC的最好的开源购物车,以及内部存储库/服务类。啊,我个人喜欢服务或核心项目中的业务逻辑,而不是web/presentation项目。如果需要添加另一个表示层或使用单独的API,我不想重复逻辑。没有正确或错误的答案。看来你已经准备好做决定了;我会说去吧。我用DTO的方法,有一个问题。当方法签名为
列表历史记录(int userId,string specialString)
时,如何返回验证错误?