4

I'm developing an asp.net mvc 5 application, in which I'm trying to set a validation for dd/MM/yyyy format, I've been struggling a lot to find an appropriate solution but no success, what I want it to accept:

24/01/2016

but it displays validation message as :

The field JoiningDate must be a date.

Here is what I've tried :

[DisplayFormat(DataFormatString = "{0:dd/MM/yyyy}", ApplyFormatInEditMode = true)]
public DateTime JoiningDate { get; set; }

Also, I want it to display the date in dd/MM/yyyy format everywhere at the user's end but this is a second part of my question, firstly, it should at least allow a valid date input. I'm stuck on this one, any help will be deeply appreciated, I've searched all over, but I'm not being able to get to the point, Thanks In Advance :)

Bilal Ahmed
  • 1,043
  • 4
  • 17
  • 32
  • Try using a datatype: [DataType(DataType.Date)] – crunchy Mar 11 '16 at 15:48
  • 1
    Please create an [MCVE](http://stackoverflow.com/help/mcve). – Matt Johnson-Pint Mar 11 '16 at 16:24
  • Assuming your server culture is one that accepts dates in `dd/MM/yyyy`, then the issue is `jquery.validate` which validates dates in the `MM/dd/yyyy` format. You have not indicated if your using a datepicker, but refer [this answer](http://stackoverflow.com/questions/27285458/jquery-ui-datepicker-and-mvc-view-model-type-datetime/27286969#27286969) for some options –  Mar 11 '16 at 21:05
  • @StephenMuecke , I tried `jquery.validate` but no success, and Now, it is displaying jQuery validation message `The value '24/01/2015' is not valid for Joining Date.` , I've been struggling on this for 2 days, and I badly need you :( – Bilal Ahmed Mar 12 '16 at 12:43
  • 1
    If your using client side validation, then you need to configure the validator (e.g. using jquery.globalize,js) as per the link. If you were not previously using client side validation, then the error suggests the culture on the server was one that did not accept dates in `dd/MM/yyyy` format (so change it, or use a custom `ModelBinder`) –  Mar 13 '16 at 01:09
  • @StephenMuecke , I used Custom ModelBinder, and the issue is resolved, Thank You so much for giving me such awesome idea :) – Bilal Ahmed Mar 14 '16 at 15:49

3 Answers3

7

The easiest way, I found was put in the web.config the code below

 <system.web>
    <globalization uiCulture="en" culture="en-GB"/>
</system.web>
Josue Morales
  • 711
  • 7
  • 6
4

There is much cleaner solution i figured out.

Client validation issues can occur because of MVC bug (even in MVC 5) in jquery.validate.unobtrusive.min.js which does not accept date/datetime format in any way. Unfortunately you have to solve it manually.

My finally working solution:

You have to include before:

@Scripts.Render("~/Scripts/jquery-3.1.1.js")
@Scripts.Render("~/Scripts/jquery.validate.min.js")
@Scripts.Render("~/Scripts/jquery.validate.unobtrusive.min.js")
@Scripts.Render("~/Scripts/moment.js")

You can install moment.js using:

Install-Package Moment.js

And then you can finally add fix for date format parser:

$(function () {
    $.validator.methods.date = function (value, element) {
        return this.optional(element) || moment(value, "DD.MM.YYYY", true).isValid();
    }
});
lukyer
  • 7,595
  • 3
  • 37
  • 31
3

I got the answer, I used custom ModelBinder, in order to resolve this issue,

Firstly, I registered this line in the application_start method in Global.asax:

ModelBinders.Binders.Add(typeof(DateTime?), new MyDateTimeModelBinder());

Here is the custom ModelBinder :

public class MyDateTimeModelBinder : DefaultModelBinder
{
    public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
    {
        var displayFormat = bindingContext.ModelMetadata.DisplayFormatString;
        var value = bindingContext.ValueProvider.GetValue(bindingContext.ModelName);

        if (!string.IsNullOrEmpty(displayFormat) && value != null)
        {
            DateTime date;
            displayFormat = displayFormat.Replace("{0:", string.Empty).Replace("}", string.Empty);
            // use the format specified in the DisplayFormat attribute to parse the date
            if (DateTime.TryParseExact(value.AttemptedValue, displayFormat, CultureInfo.InvariantCulture, DateTimeStyles.None, out date))
            {
                return date;
            }
            else
            {
                bindingContext.ModelState.AddModelError(
                    bindingContext.ModelName,
                    string.Format("{0} is an invalid date format", value.AttemptedValue)
                );
            }
        }

        return base.BindModel(controllerContext, bindingContext);
    }
}

Thanks to Darin Dimitrov's answer!

Bilal Ahmed
  • 1,043
  • 4
  • 17
  • 32