0

I am struggling with this for hours, I have model with this property

public DateTime ValidTo { get; set; }

I display this property in View with changed format

@Html.TextBoxFor(m => Model.ValidTo, "{0:dd.MM.yyyy}" })

And the problem begin when I submit the form, because the property Model.ValidTo has now value dd/MM/yyyy. The day and month switched position. It should be MM/dd/yyyy.

How to map my custom date format in the view to the date format in the model ? Can I set custom date format in the model ? I cannot set culture for the whole page, I need to do it only for one model or better do it to specific datetime property in the model.

Any idea ?

Experiment 1 - Custome Model Data Binder - Does not work

I tried solution from this answer DisplayFormat ApplyFormatInEditMode

[DateTimeFormat(Format = "dd.MM.yyyy")]
        public DateTime ValidTo { get; set; }

 public class DateTimeFormatAttribute : ValidationAttribute
    {
        public string Format { get; set; }

        public override bool IsValid(object value)
        {
            if (value == null)
                return true;

            DateTime val;
            try
            {
                val = DateTime.ParseExact(value.ToString(), Format, null);
            }
            catch (FormatException)
            {
                return false;
            }

            //Not entirely sure it'd ever reach this, but I need a return statement in all codepaths
            return val != DateTime.MinValue;
        }
    }

but in the View, default datetime format is displayed and after submitting dd.MM.yyyy format, the model behave the same.

Community
  • 1
  • 1
Muflix
  • 6,192
  • 17
  • 77
  • 153

2 Answers2

0

Try to add annotation :

[DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:MM/dd/yyyy}")]
Rai Vu
  • 1,595
  • 1
  • 20
  • 30
0

As a workaround I solved it with this way

In model, change model DateTime property to string

public string ValidTo { get; set; }

In controller

 DateTime dateTime;
 if (!DateTime.TryParse(model.ValidTo, 
     CultureInfo.GetCultureInfo("cs-CZ"), 
     DateTimeStyles.None, out dateTime))
 {
      ModelState.AddModelError(string.Empty, "ValidTo date field is not valid.");
 }

 model.ValidTo = dateTime.ToString(); // optional, it depends on the use later

 if (ModelState.IsValid) {  ... }
Muflix
  • 6,192
  • 17
  • 77
  • 153
  • Not a good idea. Your original problem was caused by a hard-coded locale (the server's). A request's locale is governed by the browser settings (eg preferred language), page settings, configuration settings or they can be set dynamically, eg per user, or based on a route (the `/en-US/` snippet you see in URLs). If you know the correct locale, set it per request – Panagiotis Kanavos Nov 10 '16 at 12:07
  • but, why do I need to know the requests locale ? I want show this specific locale (it goes as a string to the view and as a string back to the model) to all users, therefore it is hard coded – Muflix Nov 10 '16 at 12:10
  • The duplicate question shows almost *all* the ways you can change the locale dynamically, based on routes, domains, user preferences etc – Panagiotis Kanavos Nov 10 '16 at 12:11
  • All users -> set it in web.config then. Your problem was caused because you use a US locale, or your server does, and your web.config doesn't have a locale specified. Check the `globalization` element – Panagiotis Kanavos Nov 10 '16 at 12:11
  • But, I need this specific input to be shown with different locale than is the locale of the web page. I am good with US locale because the whole page is in English, but I need to change locale only in this specific one input control in the view. – Muflix Nov 10 '16 at 12:13
  • 1
    In this case I'd use a date picker control or script and ensure the date is sent as ISO8601 (2016-11-14), not as the displayed format. You should *avoid* hard-coding formats as much as possible to avoid conversion errors. .NET recognizes and parses the ISO format directly – Panagiotis Kanavos Nov 10 '16 at 12:17