MVC3: Culture is not set for ModelState on GET request?
I have the simplest model with a single Date
field that I want to validate.
The problem is that if I enter the date as dd.mm.yyyy
and submit it via GET it's not passing the validation. If I submit it via POST everything is ok.
I've explicitly set the CultureInfo to proper value for my project.
I've noticed that in case of GET ModelState.Values.ToList()[0].Value.Cu开发者_StackOverflow社区lture
is InvariantCulture, and in case of POST it's my ru-RU.
Why the Culture is not set for GET requests? Is that a proper behavior of ASP.Net? Are there workarounds?
Just for reference or if someone wants to check, here's the Model:
public class TestModel
{
[Required]
[DataType(DataType.Date)]
public DateTime Date { get; set; }
}
The view:
@using (Html.BeginForm("Index2", "Home", FormMethod.Get)) @* if that is changed to FormMethod.Post - everything's ok *@
{
@Html.ValidationSummary(true)
@Html.EditorForModel()
<input type="submit" value="Ok" />
}
And the handler:
public ActionResult Index2(TestModel model)
{
if (!ModelState.IsValid)
{
return View("Index", model);
}
return Content("Ok");
}
This is the proper MVC behavior.
GET requests leverage the query string to send data to the server, while POSTs leverage the request body.
Since URLs, including the query string, are usually "owned" by the applications developer, MVC uses the invariant culture to parse the raw string value into an object on your model. Parsing always happens within the context of a locale, so you have to understand which local will be used.
The easiest fix for this is to enter the date in an invariant format when using GETs, or to use a POST which would then use the culture of the IIS thread, or users Accept-Language header depending on you site's configuration.
Finally, you could implement IModelBinder or extend DefaultModelBinder yourself and change this behavior.
I'll also throw in a plug for Glimpse, which will show you the cultures that get used on each property/parameter being model bound.
Why the Culture is not set for GET requests?
That's by design. GET requests expect datetimes to be formatted using InvariantCulture. A workaround would be to write a custom model binder.
精彩评论