Using DataAnnotations to compare two model properties

匿名 (未验证) 提交于 2019-12-03 02:13:02

问题:

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?

回答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.



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


回答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)



回答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.



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


回答6:

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


标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!