可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
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; } }