Пользовательские атрибуты валидатора — использование других значений свойства в сообщении об ошибке

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

AViewModel{
    [DateBetweenAges(minProperty:"MinAge", maxProperty:"MaxAge", ErrorMessage = "Your age is not between {1} and {2}")]
    public DateTime? DoB { get; set; }

        public int MinAge { get; set; }
        public int MaxAge { get; set; }
}

Я подключил это с помощью адаптера и AdaptorProvider, чтобы предложить проверку клиента, следуя примеру здесь Определение пользовательских правил проверки клиента в Asp.net Core MVC, но у меня возникли проблемы с тем, чтобы сообщение об ошибке говорило правильно, например: 'Your age is not between 20 and 30'

20 и 30 — значения, прикрепленные к свойствам MinAge и MaxAge в ViewModel (устанавливаются при загрузке страницы)

в методе GetErrorMessage(ModelValidationContextBase validationContext) в адаптере у меня, похоже, вообще нет возможности получить значения в ViewModel.

в методе IsValid самого атрибута я получаю эти значения, используя отражение, выполняя

var maxprop = validationContext.ObjectType.GetProperty(MaxProperty);
var maxPropVal = maxProperty.GetValue(validationContext.ObjectInstance, null);

но это, похоже, не экземпляр объекта в адаптере, хотя проверка действительно приводит меня к ViewData, в котором он есть.

public class DateBetweenAgesAttributeAdapter : AttributeAdapterBase<DateBetweenAgesAttribute>
{
    private readonly DateBetweenAgesAttribute _attribute;

    public DateBetweenAgesAttributeAdapter(DateBetweenAgesAttribute attribute, IStringLocalizer localizer) : base(attribute, localizer)
    {
        _attribute = attribute;
    }

    public override void AddValidation(ClientModelValidationContext context)
    {
        MergeAttribute(context.Attributes, "data-val", "true");
        MergeAttribute(context.Attributes, "data-val-datebetweenages", GetErrorMessage(context));
        MergeAttribute(context.Attributes, "data-val-datebetweenages-min", _attribute.MinProperty);
        MergeAttribute(context.Attributes, "data-val-datebetweenages-max", _attribute.MaxProperty);
    }

    public override string GetErrorMessage(ModelValidationContextBase validationContext)
    {
return GetErrorMessage(validationContext.ModelMetadata,
            validationContext.ModelMetadata.GetDisplayName(),
            //would like to pass the actual minvalue in here,
            //would like to pass the actual maxvalue in here);
    }
..

как мне быть с этим??

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


person nat    schedule 22.07.2017    source источник
comment
Как вы решили эту проблему?   -  person MatterOfFact    schedule 25.03.2019


Ответы (1)


Я получил эту работу, поместив свойства атрибута в сообщение об ошибке в классе Attribute вместо адаптера, например:

[AttributeUsage(AttributeTargets.Property, AllowMultiple = false, Inherited = true)]
public class DateBetweenAgesAttribute : ValidationAttribute {
    public int MinProperty { get; set; }
    public int MaxProperty { get; set; }

    public DateBetweenAgesAttribute(int min, int max) : base() {
        MinProperty = min;
        MaxProperty = max;
        ErrorMessage = $"Your age is not between {MinProperty} and {MaxProperty}";
    }
}

тогда вам не нужно ничего делать в DateBetweenAgesAttributeAdapter.GetErrorMessage, он просто работает как есть.

person ghosttie    schedule 31.01.2020