ASP MVC:自定义验证属性

时间:2010-04-27 11:34:32

标签: c# asp.net-mvc validation asp.net-mvc-2 attributes

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

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

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不接受confirmpassword部分中的PasswordToCompareWith=ConfirmPassword

我做错了什么?

7 个答案:

答案 0 :(得分:18)

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

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 是一个新的,非常有用的验证器,实际上并非如此   部分   System.ComponentModel.DataAnnotations,   但已添加到   团队的System.Web.Mvc DLL。同时   没有特别好的名字(唯一的   比较它是检查   平等,所以也许E​​qualTo会   更明显),很容易看出来   此验证程序检查的用法   一个属性的值等于   另一个财产的价值。您可以   从代码中看,该属性   接受一个字符串属性   其他属性的名称   你在比较。经典用法   这类验证器就是我们的   正在使用它:密码   确认。

答案 1 :(得分:4)

很抱歉让您失望,但使用数据注释处理像您这样的简单案例可能会很痛苦。您可以查看this post

答案 2 :(得分:1)

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那样添加了全局模型级别的验证错误。

答案 3 :(得分:1)

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

[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]添加到您的密码属性中,无需通过......简单而且相当干净

答案 4 :(得分:0)

除非你做一些相当蹩脚的反射代码,否则你不能将引用类型传递给属性。

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

答案 5 :(得分:0)

你需要一个STATIC方法: 示例:

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

答案 6 :(得分:0)

仅举例:

 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<ModelClientValidationRule> 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