1

I am using ASP.NET MVC 4 with Razor. I am getting validation message (let's say I have 20.10.2013 in my textbox):

The field MyNullableDateField must be a date

My model code:

[DataType(DataType.Date)]
[DisplayFormat(DataFormatString = "{0:dd.MM.yyyy}", ApplyFormatInEditMode = true)]
public DateTime? MyNullableDateField { get; set; }

My razor:

@Html.EditorFor(m => m.MyNullableDateField, new { @class = "date" })

My editor template:

@model DateTime?
@Html.TextBox(string.Empty, (Model.HasValue ? Model.Value.ToShortDateString() : string.Empty), new { @class = "date" })

Why am I getting such error?

Andrei
  • 42,814
  • 35
  • 154
  • 218
  • 1
    **Duplicate** of [ASP.NET MVC3 - DateTime format](http://stackoverflow.com/questions/7835614/asp-net-mvc3-datetime-format). In short: because `DisplayFormat` is ignored by the default model binder. Create your own model binder. – CodeCaster Jun 13 '13 at 15:31

1 Answers1

2

Andrei,

Display formats are mostly for the use of the Html helpers you use on the view.

What you need is (as correctly mentioned by @CodeCaster) is a custom model binder for DateTime type. Custom model binders can be registered per type, so whenever MVC runtime sees an argument on a controller action of the same type, it would call on the custom model binder to correctly interpret posted values and create the type,

Following is a sample custom model binder type for DateTime

public class DateTimeModelBinder : DefaultModelBinder
{
    private string _customFormat;

    public DateTimeModelBinder(string customFormat)
    {
        _customFormat = customFormat;
    }

    public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
    {
        var value = bindingContext.ValueProvider.GetValue(bindingContext.ModelName);
    // use correct fromatting to format the value
        return DateTime.ParseExact(value.AttemptedValue, _customFormat, CultureInfo.InvariantCulture);
    }
}

Now you will have to tell MVC to use your new model binder for DateTime. You can do this by registering the new model binder at Application_Start

protected void Application_Start()
{
    //tell MVC all about your new custom model binder
    var binder = new DateTimeModelBinder("dd.MM.yyyy");
    ModelBinders.Binders.Add(typeof(DateTime), binder);
    ModelBinders.Binders.Add(typeof(DateTime?), binder);
}

Credit goes to this excellent article on custom model binding for datetime (http://blog.greatrexpectations.com/2013/01/10/custom-date-formats-and-the-mvc-model-binder/)

Hope this helps to get your started on the correct parth

Chintana Meegamarachchi
  • 1,798
  • 1
  • 12
  • 10