Using DataAnnotations to compare two model properties

后端 未结 6 781
你的背包
你的背包 2020-12-03 02:23

How would I go about writing a custom ValidationAttribute that compares two fields? This is the common \"enter password\", \"confirm password\" scenario. I need to be sure t

相关标签:
6条回答
  • 2020-12-03 03:02

    Make sure that your project references system.web.mvc v3.xxxxx.

    Then your code should be something like this:

    using System.Web.Mvc;
    

    . . . .

    [Required(ErrorMessage = "This field is required.")]    
    public string NewPassword { get; set; }
    
    [Required(ErrorMessage = "This field is required.")]
    [Compare(nameof(NewPassword), ErrorMessage = "Passwords don't match.")]
    public string RepeatPassword { get; set; }
    
    0 讨论(0)
  • 2020-12-03 03:02

    if you guys are using MVC 4 please try this code .. it will solve your error..

    please make one Metadataclass than in partial class impliment comfirmemail properties . check the below code for more details.

    using System;
        using System.Collections.Generic;
        using System.ComponentModel.DataAnnotations;
        using StringlenghtMVC.Comman;
        using System.Web.Mvc;
    
    using System.Collections;
    
        [MetadataType(typeof(EmployeeMetaData))] //here we call metadeta class
        public partial class Employee
        {
            public int Id { get; set; }
            public string Name { get; set; }
            public string Email { get; set; }
            public Nullable<int> Age { get; set; }
            public string Gender { get; set; }
            public Nullable<System.DateTime> HireDate { get; set; }
    
           //[CompareAttribute("Email")]
            public string ConfirmEmail { get; set; }
        }
    
        public class EmployeeMetaData
        {
            [StringLength(10, MinimumLength = 5)]
            [Required]
            //[RegularExpression(@"(([A-za-Z]+[\s]{1}[A-za-z]+))$", ErrorMessage = "Please enter Valid Name")]
            public string Name { get; set; }
    
            [Range(1, 100)]
            public int Age { get; set; }
            [CurrentDate]
            [DisplayFormat(DataFormatString = "{0:d}", ApplyFormatInEditMode = true)]
            public DateTime HireDate { get; set; }
    
            //[RegularExpression(@"^[\w-\._\%]+@(?:[\w]{2,6}$")]
            public string Email { get; set; }
    
            [System.Web.Mvc.CompareAttribute("Email")]
            public string ConfirmEmail { get; set; }
    
    
        }
    
    0 讨论(0)
  • 2020-12-03 03:12

    There is a CompareAttribute in the ASP.NET MVC 3 Framework that does this. If you are using ASP.NET MVC 2 and targeting .Net 4.0 then you could look at the implementation in the ASP.NET MVC 3 source code.

    0 讨论(0)
  • 2020-12-03 03:13

    You could have a custom validation attribute and apply it on the model and not on individual properties. Here's an example you might take a look at.

    0 讨论(0)
  • 2020-12-03 03:14

    This is a longer version of Darin's answer:

    public class CustomAttribute : ValidationAttribute
    {    
        public override bool IsValid(object value)
        {
            if (value.GetType() == typeof(Foo))
            {
               Foo bar = (Foo)value;
               //compare the properties and return the result
            }
    
            throw new InvalidOperationException("This attribute is only valid for Foo objects");
        }
    }
    

    and usage:

    [MetadataType(typeof(FooMD))]
    public partial class Foo
    {
         ... functions ...
    }
    
    [Custom]
    public class FooMD
    {
         ... other data annotations ...
    }
    

    The error will display in @Html.ValidationSummary(false)

    0 讨论(0)
  • 2020-12-03 03:21

    For future people looking at this issue, I was trying to write a validation attribute that would evaluate a regex if an object's property were a certain value. In my case, if an address was a shipping address, I didn't want PO Boxes enabled, so this is what I came up with:

    Usage

    [Required]
    public EAddressType addressType { get; set; } //Evaluate Validation attribute against this
    
    [EvaluateRegexIfPropEqualsValue(Constants.NOT_PO_BOX_REGEX, "addressType", EAddressType.Shipping, ErrorMessage = "Unable to ship to PO Boxes or APO addresses")]
    public String addressLine1 { get; set; }
    

    And here's the code for the validation attribute:

    [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false)]
    public class EvaluateRegexIfPropEqualsValue : ValidationAttribute
    {
        Regex _regex;
        string _prop;
        object _targetValue;
    
        public EvaluateRegexIfPropEqualsValue(string regex, string prop, object value)
        {
            this._regex = new Regex(regex);
            this._prop = prop;
            this._targetValue = value;
        }
    
        bool PropertyContainsValue(Object obj)
        {
            var propertyInfo = obj.GetType().GetProperty(this._prop);
            return (propertyInfo != null && this._targetValue.Equals(propertyInfo.GetValue(obj, null)));
        }
    
        protected override ValidationResult IsValid(object value, ValidationContext obj)
        {
            if (this.PropertyContainsValue(obj.ObjectInstance) && value != null && !this._regex.IsMatch(value.ToString()))
            {
                return new ValidationResult(this.ErrorMessage);
            }
            return ValidationResult.Success;
        }
    }
    
    0 讨论(0)
提交回复
热议问题