Compare属性不使用被比较属性的Display属性

本文关键字:属性 比较 Display Compare | 更新日期: 2023-09-27 18:29:01

我有一个用于更改密码的ViewModel,它使用Compare DataAnnotation,如下所示:

[Display(Name = "New Password")]
public string New { get; set; }
[Compare("New")]
[Display(Name = "Confirm Password")]
public string ConfirmPassword { get; set; }

不幸的是,Compare属性没有利用比较属性的Display属性。

错误消息显示为

'Confirm Password' and 'New' do not match.

您可以看到它使用了比较属性的Display属性,但没有使用被比较属性的。

我还将指定我不想使用ErrorMessage参数,因为那样我将对属性名称进行硬编码,而不是简单地从现有属性中获取它。我希望这个解决方案尽可能保持最佳实践。

如何使Compare属性利用比较属性的Display属性?

Compare属性不使用被比较属性的Display属性

我认为这可能是Compare属性的一些问题,因为您可以在其属性列表中看到OtherDisplayName属性,并且它正确地使用了正在装饰的属性的显示名称("Confirm Password"而不是"ConfirmPassword")。

我发现的一个解决方案是简单地创建一个继承自CompareAttribute的新类,如下所示:

public class CompareWithDisplayName : CompareAttribute
{
    public CompareWithDisplayName(string otherProperty) : base(otherProperty)
    {
    }
}

然后在您的房产上使用:

[Display(Name = "New Password")]
public string New { get; set; }

[Display(Name = "Confirm Password")]
[CompareWithDisplayName("New")]
public string ConfirmPassword { get; set; }

老实说,我不知道为什么这么做。这可能与反射有关,也可能与它计算每个属性的显示属性的顺序有关。通过创建它的自定义版本,顺序可能会改变?不管怎样,这对我来说都奏效了:)

编辑2很抱歉,忘记添加客户端验证所需的额外部分,这里对此进行了解释。您可以将其添加到Global.asax.cs文件中:

DataAnnotationsModelValidatorProvider.RegisterAdapter(typeof(CompareWithDisplayName), typeof(CompareAttributeAdapter))

或者在自定义属性上实现IClientValidatable接口。这两者都显示在链接

也许太晚了,但我在Asp.Net Core Razor Page Web App中遇到了同样的问题,简单的解决方法是创建一个具有Password和ConfirmPassword属性的新InputModel类。然后,将表单输入绑定到InputModel属性。

像这样:

    [BindProperty]
    public InputModel UserPassword { get; set; }
    public class InputModel {
      [BindProperty]
      [Display(Name = "Contraseña")]
      [Required(ErrorMessage = "La contraseña es obligatoria.")]
      [RegularExpression("^[a-zA-ZñÑ0-9]+$",ErrorMessage = "Sólo se permiten letras y números.")]
      [StringLength(12,ErrorMessage = "La contraseña no debe tener más de 12 caracteres.")]
      [MaxLength(12,ErrorMessage = "La contraseña no debe tener más de 12 caracteres.")]
      [MinLength(2,ErrorMessage = "La contraseña no debe tener menos de 2 caracteres.")]
      public string Password { get; set; }
      [BindProperty]
      [Display(Name = "Confirmación de Contraseña")]
      [Required(ErrorMessage = "La contraseña es obligatoria.")]
      [Compare(nameof(Password),ErrorMessage = "La contraseña de confirmación no coincide.")]
      public string ConfirmPassword { get; set; }
    }