繁体   English   中英

ASP MVC:自定义验证属性

[英]ASP MVC: Custom Validation Attribute

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

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

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是不接受confirmpasswordPasswordToCompareWith=ConfirmPassword一部分。

我究竟做错了什么?

根据这个链接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会更明显),从使用中很容易看出这个验证器检查一个属性的值等于另一个属性的值。 您可以从代码中看到,该属性接受一个字符串属性,该属性是您要比较的另一个属性的名称。 这种验证器的经典用法是我们在这里使用它:密码确认。

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

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

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

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

在你的情况下你需要一个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<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

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM