1 namespace System.Web.Mvc {
3 using System.Collections.Generic;
4 using System.ComponentModel.DataAnnotations;
5 using System.Diagnostics.CodeAnalysis;
6 using System.Globalization;
7 using System.Reflection;
8 using System.Web.Mvc.Resources;
10 [AttributeUsage(AttributeTargets.Property)]
11 [SuppressMessage("Microsoft.Performance", "CA1813:AvoidUnsealedAttributes", Justification = "This attribute is designed to be a base class for other attributes.")]
12 public class CompareAttribute : ValidationAttribute, IClientValidatable {
14 public CompareAttribute(string otherProperty)
15 : base(MvcResources.CompareAttribute_MustMatch) {
16 if (otherProperty == null) {
17 throw new ArgumentNullException("otherProperty");
19 OtherProperty = otherProperty;
22 public string OtherProperty { get; private set; }
24 public override string FormatErrorMessage(string name) {
25 return String.Format(CultureInfo.CurrentCulture, ErrorMessageString, name, OtherProperty);
28 protected override ValidationResult IsValid(object value, ValidationContext validationContext) {
29 PropertyInfo otherPropertyInfo = validationContext.ObjectType.GetProperty(OtherProperty);
30 if (otherPropertyInfo == null) {
31 return new ValidationResult(String.Format(CultureInfo.CurrentCulture, MvcResources.CompareAttribute_UnknownProperty, OtherProperty));
34 object otherPropertyValue = otherPropertyInfo.GetValue(validationContext.ObjectInstance, null);
35 if (!Equals(value, otherPropertyValue)) {
36 return new ValidationResult(FormatErrorMessage(validationContext.DisplayName));
41 public static string FormatPropertyForClientValidation(string property) {
42 if (property == null) {
43 throw new ArgumentException(MvcResources.Common_NullOrEmpty, "property");
45 return "*." + property;
48 public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context) {
49 yield return new ModelClientValidationEqualToRule(FormatErrorMessage(metadata.GetDisplayName()), FormatPropertyForClientValidation(OtherProperty));