如何在属性验证器被覆盖的 IsValid中等待方法?



我正试图在PropertyValidator类中使用我的数据存储库。问题是存储库中的方法是异步的。。。并且我看不到要覆盖的CCD_ 1。

using System.Collections.Generic;
using System.Threading.Tasks;
using FluentValidation.Validators;
using AccountApi.Domain.Repositories;
namespace AccountApi.Domain.Validators
{
public class UserInputValidator<TElement> : PropertyValidator
{
private IUserRepository _userRepository;
public UserInputValidator(IUserRepository userRepository)
: base("{Message}.")
{
_userRepository = userRepository;
}
protected override bool IsValid(PropertyValidatorContext context)
{
var id = (int)context.PropertyValue;
var user = await _userRepository.GetById(id); // <--- HERE is the problem  
// ..... 
return true;
}
}
} 

我试着改成这个:

protected override async Task<bool> IsValidAsync(PropertyValidatorContext context)   

但效果不太好。没有可覆盖的IsValidAsync

是否可以在PropertyValidator中使用async方法?

你走在了正确的轨道上。

是的,您确实过载了PropertyValidator方法protected virtual async Task<bool> IsValidAsync(PropertyValidatorContext context, CancellationToken cancellation)

但是,您需要使用validator.ValidateAsync(objectToValidate)方法才能使用它

如果您的验证器包含异步验证器或异步验证器条件下,务必在验证器,而从不验证。如果您调用Validate,则您的异步规则将同步运行,这是不可取的。

此外,请参阅Jeremy建议的以下问题:

  • 同时重载ShouldValidateAsync方法或更好
  • 使用AsyncValidatorBase而不是为您处理IsValidAsync0过载的PropertyValidator

如果您想查看异步属性验证器的工作解决方案,请参阅以下内容。

是否可以在PropertyValidator中使用异步方法?

您可以在vs中的PropertyValidator上按F12查看其方法。

public abstract class PropertyValidator : IPropertyValidator
{
protected PropertyValidator(IStringSource errorMessageSource);
protected PropertyValidator(string errorMessage);
[Obsolete("This constructor will be removed in FluentValidation 9.0. Use the overload that takes an IStringSource instead, passing in a LazyStringSource: PropertyValidator(new LazyStringSource(ctx => MyResourceClass.MyResourceName))")]
protected PropertyValidator(string errorMessageResourceName, Type errorMessageResourceType);
public PropertyValidatorOptions Options { get; }
public virtual bool ShouldValidateAsync(ValidationContext context);
public virtual IEnumerable<ValidationFailure> Validate(PropertyValidatorContext context);
[AsyncStateMachine(typeof(<ValidateAsync>d__7))]
public virtual Task<IEnumerable<ValidationFailure>> ValidateAsync(PropertyValidatorContext context, CancellationToken cancellation);
//
// Summary:
//     Creates an error validation result for this validator.
//
// Parameters:
//   context:
//     The validator context
//
// Returns:
//     Returns an error validation result.
protected virtual ValidationFailure CreateValidationError(PropertyValidatorContext context);
protected abstract bool IsValid(PropertyValidatorContext context);
[AsyncStateMachine(typeof(<IsValidAsync>d__10))]
protected virtual Task<bool> IsValidAsync(PropertyValidatorContext context, CancellationToken cancellation);
//
// Summary:
//     Prepares the FluentValidation.Internal.MessageFormatter of context for an upcoming
//     FluentValidation.Results.ValidationFailure.
//
// Parameters:
//   context:
//     The validator context
protected virtual void PrepareMessageFormatterForValidationError(PropertyValidatorContext context);
}

所以,试着使用

protected override async Task<bool> IsValidAsync(PropertyValidatorContext context, CancellationToken cancellation)

这很简单。只需使用";AsyncPropertyValidator";或";AsyncPropertyValidator<T、 类型>quot;

在你的情况下,它将像

using System.Collections.Generic;
using System.Threading.Tasks;
using FluentValidation.Validators;
using AccountApi.Domain.Repositories;

namespace AccountApi.Domain.Validators
{
public class UserInputValidator<TElement> : AsyncPropertyValidator
{
private IUserRepository _userRepository;
public UserInputValidator(IUserRepository userRepository)
: base("{Message}.")
{
_userRepository = userRepository;
}
public override async Task<bool> IsValidAsync(PropertyValidatorContext context)
{
var id = (int)context.PropertyValue;
var user = await _userRepository.GetById(id);
// .. 
return true;
}
}
}