ASP MVC: Custom Validation Attribute

前端 未结 7 915
说谎
说谎 2021-01-18 10:00

I\'m trying to write my own Custom Validation attribute but I\'m having some problems.

The attribute I\'m trying to write is that when a user logs in, the password w

相关标签:
7条回答
  • 2021-01-18 10:17

    You can't pass a reference type to an attribute unless you do some rather lame reflection code.

    In this situation, I would think creating a custom model binder would be a better idea and then checking the Password and ComparePassword at that point.

    0 讨论(0)
  • 2021-01-18 10:19

    I don't know why this is made out to be such a big deal, just do this:

    [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;
        }
    }
    

    Now all you need to do is add [ComparePassword] to your password property, nothing to pass... simple and fairly clean

    0 讨论(0)
  • 2021-01-18 10:24

    you need a STATIC method in your case: EXAMPLE:

            public static ValidationResult ValidateFrequency( double frequency, ValidationContext context )
        {
            if( context == null )
            {
                return ( ValidationResult.Success );
            }
      }
    
    0 讨论(0)
  • 2021-01-18 10:28

    FoolProof http://foolproof.codeplex.com/ seems to be the best solution.

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

    It is better than suggested PropertiesMustMatchAttribute as it adds the validation error for the "RetypePassword' instead of the global model level as PropertiesMustMatchAttribute does.

    0 讨论(0)
  • 2021-01-18 10:31

    According to this link http://devtrends.co.uk/blog/the-complete-guide-to-validation-in-asp.net-mvc-3-part-1 there is an special validation attribute now in 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 is a new, very useful validator that is not actually part of System.ComponentModel.DataAnnotations, but has been added to the System.Web.Mvc DLL by the team. Whilst not particularly well named (the only comparison it makes is to check for equality, so perhaps EqualTo would be more obvious), it is easy to see from the usage that this validator checks that the value of one property equals the value of another property. You can see from the code, that the attribute takes in a string property which is the name of the other property that you are comparing. The classic usage of this type of validator is what we are using it for here: password confirmation.

    0 讨论(0)
  • 2021-01-18 10:31

    just as an example:

     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)
            };
        }
    }
      }
    

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

    0 讨论(0)
提交回复
热议问题