PropertyName в дочерних валидаторах FluentValidation - PullRequest
0 голосов
/ 28 апреля 2019

Я пытаюсь что-то немного странное в FluentValidation, и я не могу заставить его работать.В модели, которую я проверяю, есть строки, и я хотел бы запустить проверки для объектов, которые они анализируют, например, что дата, сериализованная в виде строки, уже раньше, например, так:

RuleFor(x => x.SentDateString).AsDate(d => d.DateInPast());

Я признаю, что обычный способ сделать это - заставить саму модель содержать проанализированные даты и другие объекты, а затем проверить десериализованные данные, но у меня есть причины желать сделать это таким образом.

У меня есть этоработает так:

// general mechanism for adding "casting" rules
public static IRuleBuilderOptions<T, TFrom> Xform<T, TFrom, TTo>(
    this IRuleBuilder<T, TFrom> ruleBuilder,
     Func<TFrom, TTo> xform,
     Func<IRuleBuilder<TFrom, TTo>, IRuleBuilderOptions<TFrom, TTo>> innerRules)
{
    var innerValidator = new InlineValidator<TFrom>() {
        v => innerRules(v.RuleFor(x => xform(x)))
    };
    return ruleBuilder.SetValidator(innerValidator);
}

// specific rule for making a date
public static IRuleBuilder<T, string> AsDate<T>(
    this IRuleBuilder<T, string> ruleBuilder,
    Func<IRuleBuilder<string, DateTime>, IRuleBuilderOptions<string, DateTime>> innerRules)
{
    Func<string, DateTime> parseDate = (s) =>
    {
        DateTime d;
        DateTime.TryParse(s, CultureInfo.InvariantCulture, DateTimeStyles.RoundtripKind, out d);
        return d;
    };
    return Xform(ruleBuilder, parseDate, innerRules);
}

// inner rule used in validating the date object
public static IRuleBuilderOptions<T, DateTime> DateInPast<T>(this IRuleBuilder<T, DateTime> ruleBuilder) =>
    ruleBuilder.LessThan(DateTime.Now.Add(TimeSpan.FromMinutes(5)))
        .WithMessage("{PropertyName} must be in the past");

Это действительно подтверждает свойство!Однако имя свойства не передается дочернему валидатору, поэтому я получаю сообщения вроде:

  must be in the past

Где я ожидал "SentDateString" в начале этого.Я не смог понять, как заставить это работать.Есть ли простой способ?Я все делаю неправильно?

1 Ответ

0 голосов
/ 04 мая 2019

Это оказалось довольно просто, просто нужно было передать IRuleBuilderOptions вместо IRuleBuilder и затем использовать Configure для копирования отображаемого имени.

public static IRuleBuilderOptions<T, TFrom> Xform<T, TFrom, TTo>(
    this IRuleBuilderOptions<T, TFrom> ruleBuilder,
    Func<TFrom, TTo> xform,
    Func<IRuleBuilder<TFrom, TTo>, IRuleBuilderOptions<TFrom, TTo>> innerRules)
{
    var innerValidator = new InlineValidator<TFrom>() {
        v => innerRules(v.RuleFor(x => xform(x)))
                .Configure(c1 => ruleBuilder.Configure(c2 => c1.DisplayName = c2.DisplayName))
    };
    return ruleBuilder.SetValidator(innerValidator);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...