Search code examples
javascriptdatetimeasp.net-mvc-2asp.net-mvc-2-validationclient-side-validation

MVC2 Client-side validation for a DateTime?


What approach do you recommend for validating a DateTime on the client side in MVC?

Let's say I have a model with a property named DateOfBirth that is a DateTime, like so.

public class UserModel
{
    [DataType(DataType.Date)]
    public DateTime DateOfBirth {get;set;}
}

On the View, I have a simple

<%: Html.LabelFor(model=>model.DateOfBirth) %>
<%: Html.EditorFor(model=>model.DateOfBirth) %>
<%: Html.ValidationMessageFor(model=>model.DateOfBirth) %>
<input type="submit" value="Submit" />

I can use either the Microsoft MVC validations or the jQuery validations. How do I get the DateTime to validate client-side?

I realize all the DataTypeAttribute does is provide formatting hints and doesn't really do any validation (it leaves that part to the ModelBinder).

Basically I want to duplicate what the ModelBinder does when it tries to put the posted value into the model's DateOfBirth property.

What are your recommendations?


Solution

  • As suggested above, follow Phil Haack's post on custom validations: http://haacked.com/archive/2009/11/19/aspnetmvc2-custom-validation.aspx

    Here's how I would do it:


    1. Add a "DateFormatAttribute" class, like so:
    
        public class DateFormatAttribute : ValidationAttribute {
          public override bool IsValid(object value) {    
            if (value == null) {
              return true;
            }
    
            // Note: the actual server side validation still has to be implemented :-)
            // Just returning true now...
    
            return true;
          }
        }
    

    1. Add a "DateFormatValidator" class, like so:
    
        public class DateFormatValidator : DataAnnotationsModelValidator 
        {
          string message;
    
          public PriceValidator(ModelMetadata metadata, ControllerContext context
            , DateFormatAttribute attribute)
            : base(metadata, context, attribute) 
          {
            message = attribute.ErrorMessage;
          }
    
          public override IEnumerable GetClientValidationRules() 
          {
            var rule = new ModelClientValidationRule {
              ErrorMessage = message,
              ValidationType = "date" // note that this string will link to the JavaScript function we'll write later on
            };
    
            return new[] { rule };
          }
        }
    

    1. Register the above classes somewhere in Global.asax.cs:
    
        DataAnnotationsModelValidatorProvider
            .RegisterAdapter(typeof(DateFormatAttribute), typeof(DateFormatValidator));
    

    1. Add a validation function on the client. Note that this will have to be implemented attributng the locale of the user. The following is a Dutch (nl-NL, nl-BE) client-side validation function:
    
        /*
         * Localized default methods for the jQuery validation plugin.
         * Locale: NL
         */
        jQuery.extend(jQuery.validator.methods, {
            date: function(value, element) {
                return this.optional(element) || /^\d\d?[\.\/-]\d\d?[\.\/-]\d\d\d?\d?$/.test(value);
            }
        });
    

    That should cover things...