您可以访问 ASP.NET Core 2.1 MVC 客户端验证的其他属性的元数据吗?

Can you access the metadata of other properties for ASP.NET Core 2.1 MVC client side validation?

我正在考虑通过实现 IClientModelValidator 接口来实现一些非常简单的客户端验证。具体来说,我正在创建一个 NotEqualTo(后来是 EqualTo)验证属性,它将一个输入的值与另一个进行比较。

为了提供良好的用户体验,我想在错误消息中使用两个输入的显示名称:例如 "Password cannot be the same as Email"。

这显然已经完成了一百万次并且周围有很多示例,但它们要么是针对以前版本的 MVC,要么没有使用其他版本的显示名称属性。

以下是我目前所拥有的。我已经设法通过服务器端 IsValid(...) 方法中的 Display 属性获取显示名称,但我不知道如何为客户端 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));
  }        
}

通常我在休息后自己解决了这个问题,只是把它留在这里以防它帮助其他人(或者有更好的解决方案):

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

获取其他属性的元数据