Using DataAnnotations to compare two model properties

76,196

Solution 1

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.

Solution 2

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

Solution 3

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)

Solution 4

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.

Solution 5

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


    }
Share:
76,196

Related videos on Youtube

Scott
Author by

Scott

C# programmer

Updated on August 23, 2020

Comments

  • Scott
    Scott almost 4 years

    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 the two fields are equal and to keep things consistent, I want to implement the validation via DataAnnotations.

    So in pseudo-code, I'm looking for a way to implement something like the following:

    public class SignUpModel
    {
        [Required]
        [Display(Name = "Password")]
        public string Password { get; set; }
    
        [Required]
        [Display(Name = "Re-type Password")]
        [Compare(CompareField = Password, ErrorMessage = "Passwords do not match")]
        public string PasswordConfirm { get; set; }
    }
    
    public class CompareAttribute : ValidationAttribute
    {
        public CompareAttribute(object propertyToCompare)
        {
            // ??
        }
    
        public override bool IsValid(object value)
        {
            // ??
        }
    }
    

    So the question is, how do I code the [Compare] ValidationAttribute?

  • Pepito Fernandez
    Pepito Fernandez over 11 years
    In this case you can save yourself the Required attribute for the second property since you are already enforcing a comparison to the first property which is in fact Required.
  • Geoff James
    Geoff James almost 8 years
    Note that, as of C#6.0, it is now possible to use the nameof keyword, instead of using "magic strings" as property names. This makes for better/easier refactoring of any related properties, as it is using the strongly-typed property name, instead (and saves you having to remember to update the magic string (as I have done a few times)). Plus, the compiler will error if you ever missed one, somehow - thus making it "foolproof". Usage example as per @Janx's answer: [CompareAttribute(nameof(NewPassword), ErrorMessage = "Passwords don't match.")]