Как ожидать метода в переопределенном PropertyValidator IsValid? - PullRequest
0 голосов
/ 26 марта 2020

Я пытаюсь использовать мой репозиторий данных в классе PropertyValidator. Проблема в том, что метод в репозитории asyn c ... и я не вижу IsValidAsync для переопределения.

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 для переопределения.

Возможно ли использовать async методы внутри PropertyValidator?

Ответы [ 2 ]

1 голос
/ 27 марта 2020

Вы как раз на правильном пути.

Да, вы перегружаете метод PropertyValidator protected virtual async Task<bool> IsValidAsync(PropertyValidatorContext context, CancellationToken cancellation)

Однако вам нужно использовать метод validator.ValidateAsync(objectToValidate), чтобы использовать it.

Если ваш валидатор содержит асинхронные валидаторы или асинхронные условия, важно, чтобы вы всегда вызывали ValidateAsyn c для своего валидатора и никогда не валидировали. Если вы вызываете Validate, то ваши асинхронные правила будут выполняться синхронно, что нежелательно.

Источник

Дополнительно обратитесь к следующей проблеме где Джереми предлагает:

  • Также перегружает метод ShouldValidateAsync; или еще лучше
  • Используйте AsyncValidatorBase вместо PropertyValidator, который обрабатывает перегрузку ShouldValidateAsync для вас

См. Следующее, если вы хотите см. рабочий раствор валидатора asyn c.

1 голос
/ 27 марта 2020

Возможно ли использовать asyn c методы внутри PropertyValidator?

Вы можете нажать F12 на PropertyValidator в vs, чтобы увидеть его методы.

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)
...