Skip to content

Instantly share code, notes, and snippets.

@srkirkland
Created March 16, 2011 04:52
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save srkirkland/872037 to your computer and use it in GitHub Desktop.
Save srkirkland/872037 to your computer and use it in GitHub Desktop.
Extending the equal to attribute to use the display name (from model metadata)
using System;
using System.ComponentModel.DataAnnotations;
using System.Globalization;
using System.Linq;
using System.Reflection;
using DataAnnotationsExtensions.Resources;
namespace DataAnnotationsExtensions
{
/// <summary>
/// Validates that the property has the same value as the given 'otherProperty'
/// </summary>
/// <remarks>
/// From Mvc3 Futures
/// </remarks>
[AttributeUsage(AttributeTargets.Property, AllowMultiple = false)]
public class EqualToAttribute : ValidationAttribute
{
public EqualToAttribute(string otherProperty)
{
if (otherProperty == null)
{
throw new ArgumentNullException("otherProperty");
}
OtherProperty = otherProperty;
OtherPropertyDisplayName = null;
}
public string OtherProperty { get; private set; }
public string OtherPropertyDisplayName { get; set; }
public override string FormatErrorMessage(string name)
{
if (ErrorMessage == null && ErrorMessageResourceName == null)
{
ErrorMessage = ValidatorResources.CompareAttribute_MustMatch;
}
var otherPropertyDisplayName = OtherPropertyDisplayName ?? OtherProperty;
return String.Format(CultureInfo.CurrentCulture, ErrorMessageString, name, otherPropertyDisplayName);
}
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
PropertyInfo otherPropertyInfo = validationContext.ObjectType.GetProperty(OtherProperty);
if (otherPropertyInfo == null)
{
return new ValidationResult(String.Format(CultureInfo.CurrentCulture, ValidatorResources.EqualTo_UnknownProperty, OtherProperty));
}
var displayAttribute =
otherPropertyInfo.GetCustomAttributes(typeof (DisplayAttribute), false).FirstOrDefault() as DisplayAttribute;
if (displayAttribute != null && !string.IsNullOrWhiteSpace(displayAttribute.Name))
{
OtherPropertyDisplayName = displayAttribute.Name;
}
object otherPropertyValue = otherPropertyInfo.GetValue(validationContext.ObjectInstance, null);
if (!Equals(value, otherPropertyValue))
{
return new ValidationResult(FormatErrorMessage(validationContext.DisplayName));
}
return null;
}
}
}
using System;
using System.Collections.Generic;
using System.Web.Mvc;
using DataAnnotationsExtensions.ClientValidation.Resources;
namespace DataAnnotationsExtensions.ClientValidation.Adapters
{
public class EqualToAttributeAdapter : DataAnnotationsModelValidator<EqualToAttribute>
{
public EqualToAttributeAdapter(ModelMetadata metadata, ControllerContext context, EqualToAttribute attribute)
: base(metadata, context, attribute)
{
}
public override IEnumerable<ModelClientValidationRule> GetClientValidationRules()
{
Attribute.OtherPropertyDisplayName = GetOtherPropertyDisplayName();
var otherProp = FormatPropertyForClientValidation(Attribute.OtherProperty);
//We'll just use the built-in System.Web.Mvc client validation rule
return new[] { new ModelClientValidationEqualToRule(ErrorMessage, otherProp) };
}
private string GetOtherPropertyDisplayName()
{
if (Metadata.ContainerType != null && !String.IsNullOrEmpty(Attribute.OtherProperty))
{
var propertyMetaData = ModelMetadataProviders.Current.GetMetadataForProperty(() => Metadata.Model,
Metadata.ContainerType,
Attribute.OtherProperty);
return propertyMetaData.GetDisplayName();
}
return Attribute.OtherProperty;
}
public static string FormatPropertyForClientValidation(string property)
{
if (property == null)
{
throw new ArgumentException(ClientValidationResources.Common_NullOrEmpty, "property");
}
return "*." + property;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment