Question

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?

Was it helpful?

Solution

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

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top