我有一个基于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)
时,该属性为叫吗?
答案 0 :(得分:0)
您在模型中添加的数据注释旨在验证模型中存在的数据(尽管有些注释也可以转换为数据库)。即使您要在客户端框架上使用模型,也应重用这些对象。
您可以使用您提到的ModelState
函数对数据库进行异步调用。如果要从控制器中删除逻辑,则可以创建实用程序功能。
如果您愿意使用第三方库,则有一个很棒的流行验证库,名为Fluent Validation。以下是有关如何使用它进行异步调用的文档:https://docs.fluentvalidation.net/en/latest/async.html