Forked from vanillajonathan/NotBeforeAttribute.cs
Created
September 25, 2017 01:35
-
-
Save LSTANCZYK/a0e00863ae862cc66743127cbb09d0b7 to your computer and use it in GitHub Desktop.
Ensures that the end date is not prior to the start date.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.ComponentModel.DataAnnotations; | |
using System.Globalization; | |
using System.Linq; | |
using System.Reflection; | |
namespace DataAnnotations | |
{ | |
/// <summary> | |
/// Provides an attribute that compares two properties of a model and | |
/// ensures that the value of the end property is not prior to the value | |
/// of the begin property. | |
/// </summary> | |
[AttributeUsage(AttributeTargets.Property, AllowMultiple = false)] | |
public class NotBeforeAttribute : ValidationAttribute | |
{ | |
private const string NotBefore = "'{0}' can not be before '{1}'."; | |
private const string UnknownProperty = "Could not find a property named {0}."; | |
private string _otherProperty; | |
private string _otherPropertyDisplayName; | |
/// <summary> | |
/// Initializes a new instance of the <see cref="NotBeforeAttribute"/> class. | |
/// </summary> | |
/// <param name="otherProperty">The property to compare with the current property.</param> | |
public NotBeforeAttribute(string otherProperty) : base(NotBefore) | |
{ | |
_otherProperty = otherProperty ?? throw new ArgumentNullException(nameof(otherProperty)); | |
} | |
public override bool RequiresValidationContext => true; | |
public override string FormatErrorMessage(string name) | |
{ | |
return string.Format(CultureInfo.CurrentCulture, ErrorMessageString, name, | |
_otherPropertyDisplayName ?? _otherProperty); | |
} | |
protected override ValidationResult IsValid(object value, ValidationContext validationContext) | |
{ | |
var otherPropertyInfo = validationContext.ObjectType.GetRuntimeProperty(_otherProperty); | |
if (otherPropertyInfo == null) | |
{ | |
return new ValidationResult(string.Format(CultureInfo.CurrentCulture, UnknownProperty, _otherProperty)); | |
} | |
object otherPropertyValue = otherPropertyInfo.GetValue(validationContext.ObjectInstance, null); | |
if ((dynamic)value < (dynamic)otherPropertyValue) | |
{ | |
if (_otherPropertyDisplayName == null) | |
{ | |
_otherPropertyDisplayName = GetDisplayNameForProperty(validationContext.ObjectType, otherPropertyInfo); | |
} | |
return new ValidationResult(FormatErrorMessage(validationContext.DisplayName)); | |
} | |
return null; | |
} | |
private string GetDisplayNameForProperty(Type containerType, PropertyInfo property) | |
{ | |
var attributes = CustomAttributeExtensions.GetCustomAttributes(property, true); | |
var display = attributes.OfType<DisplayAttribute>().FirstOrDefault(); | |
if (display != null) | |
{ | |
return display.GetName(); | |
} | |
return _otherProperty; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment