13

Basically, my datepicker uses UK format of dd/mm/yyyy. But when I submit the form, ASP.net is clearly using US format. (will only accept days if less than 12, i.e. thinks it is the month.)

 public ActionResult TimeTable(DateTime ViewDate)

Is there a way to force it to recognise a certain way?

Strangely though, other methods of insert seem to recognise the correct format.

"The parameters dictionary contains a null entry for parameter ViewDate of non-nullable type System.DateTime for method System.Web.Mvc.ActionResult Index(System.DateTime) in Mysite.Controllers.RoomBookingsController. An optional parameter must be a reference type, a nullable type, or be declared as an optional parameter."

CodesInChaos
  • 106,488
  • 23
  • 218
  • 262
IAmGroot
  • 13,760
  • 18
  • 84
  • 154
  • Note: you also need to change the unobtrusive javascript, if you wish to save using MVC3. Else it wont even let you post. http://stackoverflow.com/questions/12053022/mvc-datetime-validation-uk-date-format – IAmGroot Jan 29 '14 at 17:00

6 Answers6

17

Have a read of this. It gives a good explanation of what's happening and why it works as it does.

I'm in the situation where I know everyone using the site is in the UK so I can safely override the default DateTime model binder:

public class DateTimeModelBinder : IModelBinder
{
    public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
    {
        var date = bindingContext.ValueProvider.GetValue(bindingContext.ModelName).AttemptedValue;

        if (String.IsNullOrEmpty(date))
            return null;

        bindingContext.ModelState.SetModelValue(bindingContext.ModelName, bindingContext.ValueProvider.GetValue(bindingContext.ModelName));
        try
        {
            return DateTime.Parse(date);
        }
        catch (Exception)
        {
            bindingContext.ModelState.AddModelError(bindingContext.ModelName, String.Format("\"{0}\" is invalid.", bindingContext.ModelName));
            return null;
        }
    }
}
Adam Flanagan
  • 3,052
  • 23
  • 31
  • Reading through the provided, it makes more sense as to the different situations. This post immediately calls a view of which the formats vary. Where as the other posts store to the DB. and hence are recognised properly. – IAmGroot Dec 12 '11 at 14:41
  • Ok, So where would I place this code / How would I reference it, to be used. Cheers – IAmGroot Dec 12 '11 at 14:52
  • 3
    I have the code above in it's own file in a Binders directory. You then need to register the binder in `Application_Start()` with something like `ModelBinders.Binders.Add(typeof(DateTime), new DateTimeModelBinder())` – Adam Flanagan Dec 13 '11 at 11:37
  • Your code is constantly inversing the datetime. so it is UK then US then UK etc etc etc. Well - It doesnt fix the display problem. There is clearly a clash in US and UK still being used, causing weird effects. im using `addday(1)` and it keeps inverting. – IAmGroot Dec 13 '11 at 13:12
  • Finally I can add comments. Consider using DateTime.TryParseExact(), you can specify your DateTime format there ("{0:dd/MM/yyyy}" – Gumowy Kaczak Dec 13 '11 at 14:00
  • While it feels a bit weird to overwrite this, it does work, With a little modification to parse it with a culture format. Why did no one edit this answer yet? – CularBytes Jan 16 '16 at 13:18
3

You need to use custom ModelBinder for your DateTime. I had that same problem as you.

Gumowy Kaczak
  • 1,457
  • 2
  • 16
  • 28
2

Have you tried setting the Current Culture as en-GB?

protected override void Initialize(System.Web.Routing.RequestContext requestContext)
{
     base.Initialize(requestContext);

     CultureInfo cultureInfo = CultureInfo.GetCultureInfo("en-GB");

     Thread.CurrentThread.CurrentCulture = cultureInfo;
     Thread.CurrentThread.CurrentUICulture = cultureInfo;                    
 }
Sebastian Piu
  • 7,838
  • 1
  • 32
  • 50
2

Basically, my datepicker uses UK format of dd/mm/yyyy

Beginner mistake. It should use whatever format the browser is set to. The problem is not a format, but different formats between client and server. The server should emit code that formats the date according to the negotiated locale which the server then also uses to parse it.

But when I submit the form, ASP.NET is clearly using US format.

Nope. This is saying that when I take a spice it always is salt and then you always take salt. Your Server accepts the currently negotiated culture which - unless you modify settings - is negotiated between client and server. Check the threads current culture when it should do the parsing to see what it is set for.

ranieuwe
  • 2,268
  • 1
  • 24
  • 30
TomTom
  • 61,059
  • 10
  • 88
  • 148
  • Ok, so if datetimepicker uses the Browser set options, it would still come in to asp.net code in the actual represented datetime regardless of datetimepickers format? – IAmGroot Dec 12 '11 at 13:21
  • Depends how you code it. Can also come as string from a badly written datetime picker. You say "MY datetime picker". Fix it ;) – TomTom Dec 12 '11 at 13:24
  • Ouch - likely totally ignorant on the settings negotiated with the server. Check http://stackoverflow.com/questions/3870605/jquery-datetime-picker-date-format-issue to see how oyu have to initialize it in the page ;) Basically tell it to use the negotiated formatting. THen they match. – TomTom Dec 12 '11 at 14:10
  • I've currently got jquery datetimepicker overridden to use UK format. My PC is in UK format, but it still reads as US in post to C# code. Even with the below override. :( Im still at a loss on how to fix it. – IAmGroot Dec 12 '11 at 14:28
2

You can do it:

  • globally (in global.asax under Application_Start() ):

    ModelBinders.Binders.Add(typeof(DateTime), new DateTimeModelBinder()); 
    
  • for a method:

        public ActionResult TimeTable([Binder(typeof(DateTimeModelBinder)]DateTime ViewDate)
    
  • for a custom model class - ah no, no posibility cause you use struct DateTime ;-)

Ah, sorry I couldn't add a comment to Adams post - it's based on his code.

Gumowy Kaczak
  • 1,457
  • 2
  • 16
  • 28
0

From my BindigTools for bindning DateTime? (Nullable), based on some book sample - Pro MVC3

    public static DateTime? GetValueNDateTime(ModelBindingContext context, string searchPrefix, string key, string format)
    {
        ValueProviderResult vpr = context.ValueProvider.GetValue(searchPrefix + key);
        DateTime outVal;
        if (DateTime.TryParseExact(vpr.AttemptedValue, format, null, System.Globalization.DateTimeStyles.None, out outVal))
        {
            return outVal;
        }
        else
        {
            return null;
        }
    }

It uses parsing exact so you shouldn't have any problem with parsed dates.

Gumowy Kaczak
  • 1,457
  • 2
  • 16
  • 28