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属性的一些问题,因为您可以在其属性列表中看到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; }
}