Skip to content

Instantly share code, notes, and snippets.

@f1code
Last active October 11, 2016 10:36
Show Gist options
  • Select an option

  • Save f1code/496f1d9b4a137ab3cb36 to your computer and use it in GitHub Desktop.

Select an option

Save f1code/496f1d9b4a137ab3cb36 to your computer and use it in GitHub Desktop.
ASP.NET MVC ValidationAttribute ensuring one date is greater than another
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Web.Mvc;
namespace WebUI.Infrastructure
{
/// <summary>
/// Validation attribute ensuring a date property is greater than another one specified.
/// </summary>
public class IsDateAfterAttribute : ValidationAttribute, IClientValidatable
{
private readonly string _compareTo;
private readonly bool _allowEqualDates;
public IsDateAfterAttribute(string compareTo, bool allowEqualDates = false)
{
_compareTo = compareTo;
_allowEqualDates = allowEqualDates;
}
/// <summary>
/// Validates the specified value with respect to the current validation attribute.
/// </summary>
/// <returns>
/// An instance of the <see cref="T:System.ComponentModel.DataAnnotations.ValidationResult"/> class.
/// </returns>
/// <param name="value">The value to validate.</param><param name="validationContext">The context information about the validation operation.</param>
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
var propertyTestedInfo = validationContext.ObjectType.GetProperty(_compareTo);
if (propertyTestedInfo == null)
{
return new ValidationResult($"Unknown property {_compareTo}");
}
var propertyTestedValue = propertyTestedInfo.GetValue(validationContext.ObjectInstance, null);
if (!(value is DateTimeOffset))
{
return ValidationResult.Success;
}
if (!(propertyTestedValue is DateTimeOffset))
{
return ValidationResult.Success;
}
if ((DateTimeOffset)value < (DateTimeOffset)propertyTestedValue ||
(!_allowEqualDates && value == propertyTestedValue))
{
return new ValidationResult(FormatErrorMessage(validationContext.DisplayName));
}
return ValidationResult.Success;
}
/// <summary>
/// When implemented in a class, returns client validation rules for that class.
/// </summary>
/// <returns>
/// The client validation rules for this validator.
/// </returns>
/// <param name="metadata">The model metadata.</param><param name="context">The controller context.</param>
public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
{
var rule = new ModelClientValidationRule();
rule.ErrorMessage = FormatErrorMessage(metadata.DisplayName);
rule.ValidationParameters.Add("compareto", "#" + _compareTo);
if (_allowEqualDates)
rule.ValidationParameters.Add("allowequaldates", "true");
rule.ValidationType = "isdateafter";
yield return rule;
}
}
}
// definition for the isdateafter validation rule
if ($.validator && $.validator.unobtrusive) {
$.validator.addMethod('isdateafter', function (value, element, params) {
value = Date.parse(value);
var otherDate = Date.parse($(params.compareTo).val());
if (isNaN(value) || isNaN(otherDate))
return true;
return value > otherDate || (value == otherDate && params.allowEqualDates);
});
$.validator.unobtrusive.adapters.add('isdateafter', ['compareto', 'allowequaldates'], function (options) {
options.rules['isdateafter'] = {
'allowEqualDates': options.params['allowequaldates'],
'compareTo': options.params['compareto']
};
options.messages['isdateafter'] = options.message;
});
}
@JamesItSolutionsLtd

Copy link
Copy Markdown

Hi this doesn't work if the compareto property is in a nested object, as the compareto id will be x_DateToCompare

@JamesItSolutionsLtd

Copy link
Copy Markdown

var otherDate = Date.parse($('[id*="_' + params.compareTo + '"]').val());

and remove the hash from
rule.ValidationParameters.Add("compareto", "#" + _compareTo);

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment