我正试图在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
而不是为您处理IsValidAsync
0过载的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;
}
}
}