ASP MVC:自定义validation属性

我正在尝试编写自己的自定义validation属性,但我遇到了一些问题。

我想写的属性是当用户登录时,密码将与确认密码进行比较。

namespace Data.Attributes { public class ComparePassword : ValidationAttribute { public string PasswordToCompareWith { get; set; } public override bool IsValid(object value) { if (PasswordToCompareWith == (string)value) { return true; } return false; } } 

现在我的问题是当我试图在模型文件中设置这样的属性时:

  [Required] [ComparePassword(PasswordToCompareWith=ConfirmPassword)] public string Password { get; set; } [Required] public string ConfirmPassword { get; set; } } 

我收到以下错误:

错误1非静态字段,方法或属性’Project.Data.Models.GebruikerRegistreerModel.ConfirmPassword.get’需要对象引用

似乎VS不接受PasswordToCompareWith=ConfirmPassword部分中的确认PasswordToCompareWith=ConfirmPassword

我究竟做错了什么?

很抱歉让您失望,但使用数据注释处理像您这样的简单案例可能会很痛苦。 你可以看一下这篇文章 。

根据此链接http://devtrends.co.uk/blog/the-complete-guide-to-validation-in-asp.net-mvc-3-part-1 ,现在MVC3中有一个特殊的validation属性:

 public class RegisterModel { // skipped [Required] [ValidatePasswordLength] [DataType(DataType.Password)] [Display(Name = "Password")] public string Password { get; set; } [DataType(DataType.Password)] [Display(Name = "Confirm password")] [Compare("Password", ErrorMessage = "The password and confirmation do not match.")] public string ConfirmPassword { get; set; } } 

CompareAttribute是一个新的,非常有用的validation器,它实际上不是System.ComponentModel.DataAnnotations的一部分,但已由团队添加到System.Web.Mvc DLL中。 虽然没有特别好的名称(它唯一的比较是检查相等性,所以也许E​​qualTo会更明显),从使用中很容易看出这个validation器检查一个属性的值等于另一个属性的值。 您可以从代码中看到,该属性接受一个字符串属性,该属性是您要比较的另一个属性的名称。 这种validation器的经典用法是我们在这里使用它:密码确认。

FoolProof http://foolproof.codeplex.com/似乎是最好的解决方案。

 public class SignUpViewModel { [Required] public string Password { get; set; } [EqualTo("Password", ErrorMessage="Passwords do not match.")] public string RetypePassword { get; set; } } 

它比建议的PropertiesMustMatchAttribute更好,因为它为“RetypePassword”而不是像PropertiesMustMatchAttribute那样添加了全局模型级别的validation错误。

我不知道为什么这是一个大问题,只需这样做:

 [AttributeUsage(AttributeTargets.Property, AllowMultiple = true, Inherited = false)] public class ComparePassword: ValidationAttribute { public ComparePassword() : base("Passwords must match.") { } protected override ValidationResult IsValid (object value, ValidationContext validationContext) { if (value == null) return new ValidationResult("A password is required."); // Make sure you change YourRegistrationModel to whatever the actual name is if ((validationContext.ObjectType.Name != "YourRegistrationModel") return new ValidationResult("This attribute is being used incorrectly."); if (((YourRegistrationModel)validationContext.ObjectInstance).ConfirmPassword != value.ToString()) return new ValidationResult("Passwords must match."); return ValidationResult.Success; } } 

现在您需要做的就是将[ComparePassword]添加到您的密码属性中,无需通过……简单而且相当干净

除非您执行一些相当蹩脚的reflection代码,否则无法将引用类型传递给属性。

在这种情况下,我认为创建一个自定义模型绑定器是一个更好的主意,然后检查密码和ComparePassword。

在你的情况下你需要一个STATIC方法:例子:

  public static ValidationResult ValidateFrequency( double frequency, ValidationContext context ) { if( context == null ) { return ( ValidationResult.Success ); } } 

举个例子:

  using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using System.Globalization; using System.Web.Mvc; using System.Web.Security; namespace GDNET.Web.Mvc.Validation { [AttributeUsage(AttributeTargets.Field | AttributeTargets.Property, AllowMultiple = false, Inherited = true)] public sealed class ValidatePasswordLengthAttribute : ValidationAttribute, IClientValidatable { private const string defaultErrorMessage = "'{0}' must be at least {1} characters long."; private readonly int minRequiredPasswordLength = Membership.Provider.MinRequiredPasswordLength; public ValidatePasswordLengthAttribute() : base(defaultErrorMessage) { } public override string FormatErrorMessage(string name) { return String.Format(CultureInfo.CurrentCulture, ErrorMessageString, name, minRequiredPasswordLength); } public override bool IsValid(object value) { string valueAsString = value as string; return (valueAsString != null && valueAsString.Length >= minRequiredPasswordLength); } public IEnumerable GetClientValidationRules(ModelMetadata metadata, ControllerContext context) { return new[] { new ModelClientValidationStringLengthRule(FormatErrorMessage(metadata.GetDisplayName()), minRequiredPasswordLength, int.MaxValue) }; } } } 

来源: https : //code.google.com/p/gdnetprojects/source/browse/trunk/Experiments/Common/GDNET.Web.Mvc/Validation/ValidatePasswordLengthAttribute.cs?r = 69