e79aa3c0ed
Former-commit-id: a2155e9bd80020e49e72e86c44da02a8ac0e57a4
79 lines
3.5 KiB
C#
79 lines
3.5 KiB
C#
namespace System.ComponentModel.DataAnnotations {
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.ComponentModel;
|
|
using System.ComponentModel.DataAnnotations;
|
|
using System.ComponentModel.DataAnnotations.Resources;
|
|
using System.Diagnostics.CodeAnalysis;
|
|
using System.Globalization;
|
|
using System.Linq;
|
|
using System.Reflection;
|
|
|
|
[AttributeUsage(AttributeTargets.Property, AllowMultiple = false)]
|
|
[SuppressMessage("Microsoft.Performance", "CA1813:AvoidUnsealedAttributes", Justification = "This attribute is designed to be a base class for other attributes.")]
|
|
public class CompareAttribute : ValidationAttribute {
|
|
|
|
public CompareAttribute(string otherProperty)
|
|
: base(DataAnnotationsResources.CompareAttribute_MustMatch) {
|
|
if (otherProperty == null) {
|
|
throw new ArgumentNullException("otherProperty");
|
|
}
|
|
OtherProperty = otherProperty;
|
|
}
|
|
|
|
public string OtherProperty { get; private set; }
|
|
|
|
public string OtherPropertyDisplayName { get; internal set; }
|
|
|
|
public override string FormatErrorMessage(string name) {
|
|
return String.Format(CultureInfo.CurrentCulture, ErrorMessageString, name, OtherPropertyDisplayName ?? OtherProperty);
|
|
}
|
|
|
|
public override bool RequiresValidationContext {
|
|
get {
|
|
return true;
|
|
}
|
|
}
|
|
|
|
protected override ValidationResult IsValid(object value, ValidationContext validationContext) {
|
|
PropertyInfo otherPropertyInfo = validationContext.ObjectType.GetProperty(OtherProperty);
|
|
if (otherPropertyInfo == null) {
|
|
return new ValidationResult(String.Format(CultureInfo.CurrentCulture, DataAnnotationsResources.CompareAttribute_UnknownProperty, OtherProperty));
|
|
}
|
|
|
|
object otherPropertyValue = otherPropertyInfo.GetValue(validationContext.ObjectInstance, null);
|
|
if (!Equals(value, otherPropertyValue)) {
|
|
if (OtherPropertyDisplayName == null) {
|
|
OtherPropertyDisplayName = GetDisplayNameForProperty(validationContext.ObjectType, OtherProperty);
|
|
}
|
|
return new ValidationResult(FormatErrorMessage(validationContext.DisplayName));
|
|
}
|
|
return null;
|
|
}
|
|
|
|
private static string GetDisplayNameForProperty(Type containerType, string propertyName) {
|
|
ICustomTypeDescriptor typeDescriptor = GetTypeDescriptor(containerType);
|
|
PropertyDescriptor property = typeDescriptor.GetProperties().Find(propertyName, true);
|
|
if (property == null) {
|
|
throw new ArgumentException(String.Format(CultureInfo.CurrentCulture,
|
|
DataAnnotationsResources.Common_PropertyNotFound, containerType.FullName, propertyName));
|
|
}
|
|
IEnumerable<Attribute> attributes = property.Attributes.Cast<Attribute>();
|
|
DisplayAttribute display = attributes.OfType<DisplayAttribute>().FirstOrDefault();
|
|
if (display != null) {
|
|
return display.GetName();
|
|
}
|
|
DisplayNameAttribute displayName = attributes.OfType<DisplayNameAttribute>().FirstOrDefault();
|
|
if (displayName != null) {
|
|
return displayName.DisplayName;
|
|
}
|
|
return propertyName;
|
|
}
|
|
|
|
private static ICustomTypeDescriptor GetTypeDescriptor(Type type) {
|
|
return new AssociatedMetadataTypeTypeDescriptionProvider(type).GetTypeDescriptor(type);
|
|
}
|
|
|
|
}
|
|
}
|