Я смотрю на реализацию довольно простой проверки на стороне клиента с помощью интерфейса 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));
}
}