MVC DateTime validation failing
Asked Answered
R

3

6

I found a lot of simulair questions but not a good clean solution that is working. I see a lot of custom code for getting this to work but why is that? Should this not working from the start?

What I think is strange, is that in IE9 it works but in Firefox and Chrome it is failing. Everytime that im trying in Firefox or Chrome, I get the message "The field Birthday must be a date".

When I try the code below in a new MVC 4 RTM project, I can't get it to work. I see the DateTime.Now default as dd-MM-yyyy (Holland) in all the browsers but I can't submit it in Firefox and Chrome.

The globalization tag isn't set in web.config so it must be using the default. Im from Holland so it should get the client culture I guess.

public class RegisterModel
{
    [Required]
    [Display(Name = "User name")]
    public string UserName { get; set; }

    [Required]
    [DisplayFormat(DataFormatString = "{0:d}", ApplyFormatInEditMode = true)]
    //[DataType(DataType.Date)]
    public DateTime Birthday { get; set; }
}

[AllowAnonymous]
    public ActionResult Register()
    {
        RegisterModel vm = new RegisterModel()
        {
            Birthday = DateTime.Now
        };
        return View(vm);
    }

    [HttpPost]
    [AllowAnonymous]
    [ValidateAntiForgeryToken]
    public ActionResult Register(RegisterModel model)
    {
        if (ModelState.IsValid)
        {
            // Attempt to register the user
            try
            {
                //WebSecurity.CreateUserAndAccount(model.UserName, model.Password);
                //WebSecurity.Login(model.UserName, model.Password);
                return RedirectToAction("Index", "Home");
            }
            catch (MembershipCreateUserException e)
            {
                ModelState.AddModelError("", ErrorCodeToString(e.StatusCode));
            }
        }

        // If we got this far, something failed, redisplay form
        return View(model);
    }

Markup

<!-- language: lang-none -->
@model DateTimeWithDatePicker.Models.RegisterModel
@{
   ViewBag.Title = "Register";
}

<hgroup class="title">
    <h1>@ViewBag.Title.</h1>
    <h2>Create a new account.</h2>
</hgroup>

@using (Html.BeginForm()) {
    @Html.AntiForgeryToken()
    @Html.ValidationSummary()

    <fieldset>
        <legend>Registration Form</legend>
        <ol>
            <li>
                @Html.LabelFor(m => m.UserName)
                @Html.TextBoxFor(m => m.UserName)
            </li>
            <li>
                @Html.LabelFor(m => m.Birthday)
                @Html.EditorFor(m => m.Birthday)
            </li>
        </ol>
        <input type="submit" value="Register" />
    </fieldset>
}

@section Scripts {
    @Scripts.Render("~/bundles/jqueryval")
}
Recommendatory answered 24/8, 2012 at 7:58 Comment(1)
Sorry but I don't know how to format the MVC View above.Recommendatory
R
3

The problem was jQuery validation and localization. It seems that there are localization files for messages and methods of the jQuery plugin. See my blog for a detail explaination of the problem and how I solved it.

http://www.locktar.nl/programming/mvc/localization-validation-in-mvc/

Edit: I just released a new blog post with a refresh of all the localization problems and how to fix it for a DateTime property. See my new post MVC localization validation.

Recommendatory answered 10/9, 2012 at 7:17 Comment(2)
I have used ajax.aspnetcdn.com/ajax/jquery.validate/1.7/localization/…, I found following your link. This worked fine in IE and Firefox, but not in Chrome. Chrome supports html5 date input and stores the value in format "yyyy-mm-dd". I have changed the test to: if (Modernizr.inputtypes.date) { return true; } else { <original test> }Coelacanth
Have you changed 1.7 to the newest version? It it some time ago i've written that blog. I just launched my new blog site at www.locktar.nl.Recommendatory
U
7

I was able to fix this by modifying the jQuery validator function for dates:

 <script type="text/javascript">

  $(function () {

    var dateFormat="dd/mm/yy"; // en-gb date format, substitute your own

    $("#Birthday").datepicker({
        "dateFormat": dateFormat
    });

    jQuery.validator.addMethod(
        'date',
        function (value, element, params) {
            if (this.optional(element)) {
                return true;
            };
            var result = false;
            try {
                $.datepicker.parseDate(dateFormat, value);
                result = true;
            } catch (err) {
                result = false;
            }
            return result;
        },
        ''
    );

});

Unwinking answered 20/12, 2012 at 17:38 Comment(2)
See my response on my own topic. I made a blogpost about it https://mcmap.net/q/1669927/-mvc-datetime-validation-failingRecommendatory
I tried your blog post when trying to solve this problem. I am sure that its the best solution when you want a conclusive solution for many users in different countries. But the script above is suitable when you need a two minute solution and you dont care about localisation for multi country user base.Unwinking
R
3

The problem was jQuery validation and localization. It seems that there are localization files for messages and methods of the jQuery plugin. See my blog for a detail explaination of the problem and how I solved it.

http://www.locktar.nl/programming/mvc/localization-validation-in-mvc/

Edit: I just released a new blog post with a refresh of all the localization problems and how to fix it for a DateTime property. See my new post MVC localization validation.

Recommendatory answered 10/9, 2012 at 7:17 Comment(2)
I have used ajax.aspnetcdn.com/ajax/jquery.validate/1.7/localization/…, I found following your link. This worked fine in IE and Firefox, but not in Chrome. Chrome supports html5 date input and stores the value in format "yyyy-mm-dd". I have changed the test to: if (Modernizr.inputtypes.date) { return true; } else { <original test> }Coelacanth
Have you changed 1.7 to the newest version? It it some time ago i've written that blog. I just launched my new blog site at www.locktar.nl.Recommendatory
Q
1

The globalization tag isn't set in web.config so it must be using the default. Im from Holland so it should get the client culture I guess.

No, that's not correct. You could be perfectly fine from Holland and have configured your browser to use Chinese culture. The reason you cannot get this to work is probably because in FF and Chrome you don't have the correct culture.

Since you haven't specified a culture in your globalization element in web.config, ASP.NET MVC will use the one sent from the browser in the request header. For example if you configure your browser for en-US culture the following header will be set along each request:

Accept-Language:en-US,en;q=0.8

Here's how this is configured in Chrome:

enter image description here

So make sure you've put your desired language first in the list.

And if you want a reliable way to use the same syntax as the one defined in your DisplayFormat attribute during model binding you could write a custom model binder as shown here: https://mcmap.net/q/490017/-asp-net-mvc3-datetime-format

Queer answered 24/8, 2012 at 8:2 Comment(1)
My culture was good in firefox and chrome so that wasn't the problem. The problem was jQuery validation that wasn't working in Firefox and Chrome the same as in Internet Explorer. See the answer of this post and my blog the goes into details.Recommendatory

© 2022 - 2024 — McMap. All rights reserved.