Можете ли вы получить доступ к метаданным других свойств для проверки на стороне клиента MVC ASP.NET Core 2.1? - PullRequest
0 голосов
/ 12 июня 2018

Я смотрю на реализацию довольно простой проверки на стороне клиента с помощью интерфейса IClientModelValidator.В частности, я создаю NotEqualTo (а затем EqualTo) атрибут проверки, который будет сравнивать значение одного входа с другим.

Чтобы обеспечить хороший UX, я хочу использовать отображаемое имя обоих входов в сообщениях об ошибках: например, «Пароль не может совпадать с адресом электронной почты».

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

Ниже приведено то, что я имею до сих пор.Мне удалось получить отображаемое имя с помощью атрибута Display в методе IsValid(...) на стороне сервера, но я не могу понять, как сделать подобное для метода AddValidation(...) на стороне клиента.

[AttributeUsage(AttributeTargets.Property, AllowMultiple = false, Inherited = true)]
public class NotEqualToAttribute : ValidationAttribute, IClientModelValidator
{
  private const string defaultErrorMessage = "{0} cannot be the same as {1}.";

  public string OtherProperty { get; private set; }

  public NotEqualToAttribute(string otherProperty) : base(defaultErrorMessage)
  {
    this.OtherProperty = otherProperty;
  }

  public override string FormatErrorMessage(string name) 
  {
    string.Format(base.ErrorMessageString, name, this.OtherProperty);
  }

  public void AddValidation(ClientModelValidationContext context)
  {
    context.Attributes.Add("data-val", "true");      
    context.Attributes.Add("data-val-notequalto", this.FormatErrorMessage(context.ModelMetadata.GetDisplayName());
    context.Attributes.Add("data-val-notequalto-otherproperty", this.otherProperty);
  }

  protected override ValidationResult IsValid(object value, ValidationContext validationContext)
  {
    if (value == null)
      return ValidationResult.Success;

    PropertyInfo otherProperty = validationContext.ObjectInstance.GetType().GetProperty(this.OtherProperty);
    object otherValue = otherProperty.GetValue(validationContext.ObjectInstance, null);

    if (!value.Equals(otherValue))
      return ValidationResult.Success;

    DisplayAttribute display = otherProperty.GetCustomAttribute<DisplayAttribute>();
    string otherName = display?.GetName() ?? this.OtherProperty;

    return new ValidationResult(string.Format(defaultErrorMessage, validationContext.DisplayName, otherName));
  }        
}

1 Ответ

0 голосов
/ 12 июня 2018

Обычно я решал это сам после перерыва, просто собираюсь оставить это здесь на случай, если это поможет кому-то другому (или есть лучшее решение):

public void AddValidation(ClientModelValidationContext context)
{            
  context.Attributes.Add("data-val", "true");

  string otherName = 
    context.ModelMetadata.ContainerMetadata.Properties
      .Single(p => p.PropertyName == this.OtherProperty)
      .GetDisplayName();

  context.Attributes.Add("data-val-notequalto", 
    string.Format(defaultErrorMessage, context.ModelMetadata.GetDisplayName(), otherName)
  );
}

Вы можете получить метаданныедля других свойств через ClientModelValidationContext.ModelMetadata.ContainerMetadata.Properties

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...