Note that there are some explanatory texts on larger screens.

plurals
  1. POMVC custom validation: compare two dates
    primarykey
    data
    text
    <p>I've created a custom ValidationAttribute that compares 2 dates and makes sure that the second date is greater than the first:</p> <pre><code>public sealed class IsDateAfter : ValidationAttribute, IClientValidatable { private readonly string testedPropertyName; private readonly bool allowEqualDates; public IsDateAfter(string testedPropertyName, bool allowEqualDates = false) { this.testedPropertyName = testedPropertyName; this.allowEqualDates = allowEqualDates; } protected override ValidationResult IsValid(object value, ValidationContext validationContext) { var propertyTestedInfo = validationContext.ObjectType.GetProperty(this.testedPropertyName); if (propertyTestedInfo == null) { return new ValidationResult(string.Format("unknown property {0}", this.testedPropertyName)); } var propertyTestedValue = propertyTestedInfo.GetValue(validationContext.ObjectInstance, null); if (value == null || !(value is DateTime)) { return ValidationResult.Success; } if (propertyTestedValue == null || !(propertyTestedValue is DateTime)) { return ValidationResult.Success; } // Compare values if ((DateTime)value &gt;= (DateTime)propertyTestedValue) { if (this.allowEqualDates) { return ValidationResult.Success; } if ((DateTime)value &gt; (DateTime)propertyTestedValue) { return ValidationResult.Success; } } return new ValidationResult(FormatErrorMessage(validationContext.DisplayName)); } public IEnumerable&lt;ModelClientValidationRule&gt; GetClientValidationRules(ModelMetadata metadata, ControllerContext context) { var rule = new ModelClientValidationRule { ErrorMessage = this.ErrorMessageString, ValidationType = "isdateafter" }; rule.ValidationParameters["propertytested"] = this.testedPropertyName; rule.ValidationParameters["allowequaldates"] = this.allowEqualDates; yield return rule; } </code></pre> <p>CalendarEntry class: ...</p> <pre><code>public virtual DateTime StartDate { get; set; } [IsDateAfter("StartDate", true, ErrorMessage="End date needs to be after start date")] public virtual DateTime EndDate { get; set; } </code></pre> <p>VIEW:</p> <pre><code>$.validator.unobtrusive.adapters.add( 'isdateafter', ['propertytested', 'allowequaldates'], function (options) { options.rules['isdateafter'] = options.params; options.messages['isdateafter'] = options.message; }); $.validator.addMethod("isdateafter", function(value, element, params) { alert(params.propertytested); var startdatevalue = $('input[name="' + params.propertytested + '"]').val(); if (!value || !startdatevalue) return true; return (params.allowequaldates) ? Date.parse(startdatevalue) &lt;= Date.parse(value) : Date.parse(startdatevalue) &lt; Date.parse(value); }, ''); </code></pre> <p>This works fine when the <strong>CalendarEntry</strong> is not wrapped inside another class. HOWEVER, when I use a view model like so:</p> <pre><code> public class TrainingDateEditViewModel { #region Properties /// &lt;summary&gt; /// Gets or sets CalendarEntry. /// &lt;/summary&gt; public CalendarEntry CalendarEntry { get; set; } .... </code></pre> <p>The client validation no longer works because the html output produced is this:</p> <pre><code>&lt;input type="text" value="" name="CalendarEntry.EndDate" id="CalendarEntry_EndDate" data-val-isdateafter-propertytested="StartDate" data-val-isdateafter-allowequaldates="True" data-val-isdateafter="End date needs to be after start date" data-val="true"&gt; </code></pre> <p>And the </p> <pre><code>data-val-isdateafter-propertytested="StartDate" and IT SHOULD BE: "CalendarEntry.StartDate". </code></pre> <p>How would I make it so that it would know to bind to "CalendarEntry.StartDate" rule.ValidationParameters["propertytested"] = this.testedPropertyName; // HERE IT SHOULD BE FULL NAME??? HOW??</p> <p>thanks</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload