Reputation: 3104
I have DateTime field in my model. The format in which I send date from frontend is d.m.Y H:i
. And it is parsed ok.
But when I set US date format to be sent from frontend and set culture to en-US
by typing Thread.CurrentThread.CurrentCulture = new CultureInfo("en-US")
in OnActionExecuting
method which is run before my controller action it says that date is not valid at if (ModelState.IsValid)
.
My question is where in Asp.Net framework is set that default format is d.m.Y H:i
and how can I change that default format? Does binder takes culture into consideration or it is always d.m.Y H:i
?
Upvotes: 2
Views: 247
Reputation: 3104
Thanks Vadim for your solution, but I found what is going on and solved it without custom date binder.
The problem is that parameter binding is done before the OnActionExecuting
method where I put Thread.CurrentThread.CurrentCulture = new CultureInfo("en-US")
, so the culture was still the default one when binding was done. And default culture is the one which is set in in Windows (system locale).
I changed it by putting <globalization culture="en-US"/>
in <system.web>
in Web.config
.
So now binder parses US date correctly.
Upvotes: 1
Reputation: 8892
I solved the same issue with custom data binder that I added to my project.
First, I add new class DateTimeModelBinder
:
public class DateTimeModelBinder : DefaultModelBinder
{
public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
var value = bindingContext.ValueProvider.GetValue(bindingContext.ModelName);
if (value != null)
{
DateTime time;
// here you can add your own logic to parse input value to DateTime
//if (DateTime.TryParseExact(value.AttemptedValue, "d.m.Y H:i", CultureInfo.InvariantCulture, DateTimeStyles.None, out time))
if (DateTime.TryParse(value.AttemptedValue, Culture.Ru, DateTimeStyles.None, out time))
{
return time;
}
else
{
bindingContext.ModelState.AddModelError(bindingContext.ModelName,
string.Format("Date {0} is not in the correct format", value.AttemptedValue));
}
}
return base.BindModel(controllerContext, bindingContext);
}
}
And then I add my bindeg in the Global.asax.cs
on the application startup:
protected void Application_Start(object sender, EventArgs eventArgs)
{
ModelBinders.Binders.Add(typeof(DateTime), new ateTimeModelBinder());
}
Upvotes: 1