是否可以通过ASP.NET Core异步使用数据注释来验证属性?

时间:2020-05-07 22:49:23

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

我有一个基于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)时,该属性为叫吗?

1 个答案:

答案 0 :(得分:0)

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

您可以使用您提到的ModelState函数对数据库进行异步调用。如果要从控制器中删除逻辑,则可以创建实用程序功能。

如果您愿意使用第三方库,则有一个很棒的流行验证库,名为Fluent Validation。以下是有关如何使用它进行异步调用的文档:https://docs.fluentvalidation.net/en/latest/async.html