【问题标题】:Is it possible to validate a property using data-annotation asynchronously with ASP.NET Core?是否可以使用数据注释与 ASP.NET Core 异步验证属性?
【发布时间】:2020-05-08 08:43:22
【问题描述】:

我有一个基于 asp.net core 3.1 的项目。我需要添加一个自定义验证规则,该规则需要一个数据库调用才能确定值的有效性。

例如,当创建一个新用户时,我需要在允许创建用户之前验证数据库中没有其他用户名具有相同的用户名。

如果我可以创建自定义属性UniqueUsername,那么我应该可以做这样的事情

public class UniqueUsername : ValidationAttribute
{
    private readonly UserManager _manager = manager;

    public UniqueUsername (UserManager manager)
    {
       _manager = manager;
    }

    protected override ValidationResult IsValid(object value, ValidationContext validationContext)
    {
        string username = value.ToString();

        if(_manager.Exists(username)) 
        {
             return new ValidationResult("The username provided belong to a different user.");
        }
        return ValidationResult.Success;
    }
}

但是,_manager.Exists(username) 是一个同步调用。我想避免阻塞主线程,所以我想要一种调用await _manager.ExistsAsync(username) 的方法来避免阻塞主线程。

有没有办法创建一个属性来验证单个属性并将错误“如果有”写入ModelState

如果使用数据注释无法做到这一点,是否有不同的方法来验证属性,同时将错误写入ModelState,因此当调用ModelState.IsValid()TryValidateModel(model) 时,会调用属性?

【问题讨论】:

  • 一般来说,我会避免在ValidationAttribute 内进行数据库调用,因为它们不太适合依赖注入,并且通常被认为是轻量级和快速的。请记住,您始终可以通过ModelState.AddModelError() 将您自己的自定义错误添加到ModelState——或者作为自定义IModelBinder 的一部分,或者简单地作为从控制器操作中调用的一些逻辑。如果出现任何错误,ModelState.IsValid() 将返回 false,您将能够像往常一样处理验证错误。

标签: asp.net asp.net-core data-annotations asp.net-core-3.0 asp.net-core-3.1


【解决方案1】:

您在模型中添加的数据注释旨在验证模型中存在的数据(尽管有些也可以翻译到您的数据库中)。即使您要在客户端框架上使用模型,这些也可以重复使用。

您可以使用您提到的ModelState 函数对您的数据库进行异步调用。如果您想从控制器中删除逻辑,您可以创建实用函数来执行此操作。

如果您对第三方库持开放态度,则有一个非常受欢迎的验证库,名为 Fluent Validation。这是有关如何使用它进行异步调用的文档:https://docs.fluentvalidation.net/en/latest/async.html

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-06
    • 2011-08-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多