C# 异步自定义视图模型验证。无法使用.net内核?为什么?

C# 异步自定义视图模型验证。无法使用.net内核?为什么?,c#,validation,.net-core,asp.net-core-mvc,C#,Validation,.net Core,Asp.net Core Mvc,我正在看这个文档。看起来很有用。例如,我有以下视图模型: class CustomerViewModel { public string Name {get; set;} public List<int> Roles {get; set;} } 还有惊喜!这是不可能的。它不起作用。因为没有异步版本的验证( 是否可以在模型中验证我的模型?或者我必须编写单独的验证服务?验证管道不是异步的,因此不可能用于此目的。但是,这不是它的目的。验证是为了确保类型和值的正确性,而不是

我正在看这个文档。看起来很有用。例如,我有以下视图模型:

class CustomerViewModel
{
    public string Name {get; set;}
    public List<int> Roles {get; set;}
}
还有惊喜!这是不可能的。它不起作用。因为没有异步版本的
验证

是否可以在模型中验证我的模型?或者我必须编写单独的验证服务?

验证管道不是异步的,因此不可能用于此目的。但是,这不是它的目的。验证是为了确保类型和值的正确性,而不是像实际角色值这样的业务规则。这uld将在您的业务/数据层中强制实施。例如,如果您使用DDD,则在将角色添加到角色集合时,聚合将强制实施。这也可能是在存储库或服务中强制实施的类型。此外,在关系数据库中,这将通过引用约束强制实施,这将ld冒泡进入您的数据层,例如EF抛出异常。

我没有尝试过,但您可以尝试吗

    public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
    {
        var domainService = validationContext.GetService<IMyDomainService>();
        var task = domainService.GetRoles();
        Task.WaitAll(task);
        var result = task.Result;
        
        // do your validation            
    }
公共IEnumerable验证(ValidationContext ValidationContext) { var domainService=validationContext.GetService(); var task=domainService.GetRoles(); Task.WaitAll(任务); var result=task.result; //进行验证 } 您需要使用Microsoft.Extensions.DependencyInjection添加

您还可以获得DBContext实例,而不是DomainService

@SalahAkbari-ohh(Stephen Cleary的回答告诉我,从hood开始的验证是同步的(我不明白为什么Microsoft不能提供这种功能)(@SalahAkbari解决这种情况的方法是什么?我的意思是,例如,你有问题中提到的视图模型。你需要确保所有角色都存在。你将在哪里这样做?我认为这不应该被验证。它实际上与一些业务错误有关。或者客户正在尝试破解(非通过官方用户界面发布请求)或者在用户加载UI和用户发布请求之间缺少/删除了某个角色。因此,这种情况的发生率相当低,您可以完全依赖引发异常的机制。这就是问题所在。当然,这里需要自定义异常来帮助确定问题。我通常会实现一些类似于在我的服务层上验证业务数据。现在我明白了,这是正确的。谢谢。这是层。随着你越来越接近金属,很难给用户提供良好的反馈/允许他们纠正错误。但是,有些东西只能在较低层进行验证。想想客户端验证和服务器端验证。客户端can捕获很多,但您仍然需要在服务器上进行验证,有时还需要将用户发送回。不应该只使用一个层进行验证。让这些不同的层在不同的位置捕获问题,并共同确保良好的用户体验和数据完整性。但是如何传递验证错误消息?我通常会通过我的自定义异常输入它。
    public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
    {
        var domainService = validationContext.GetService<IMyDomainService>();
        var task = domainService.GetRoles();
        Task.WaitAll(task);
        var result = task.Result;
        
        // do your validation            
    }