I would like to write my own model binder for DateTime
type. First of all I'd like to write a new attribute that I can attach to my model property like:
[DateTimeFormat("d.M.yyyy")]
public DateTime Birth { get; set,}
This is the easy part. But the binder part is a bit more difficult. I would like to add a new model binder for type DateTime
. I can either
IModelBinder
interface and write my own BindModel()
methodDefaultModelBinder
and override BindModel()
methodMy model has a property as seen above (Birth
). So when the model tries to bind request data to this property, my model binder's BindModel(controllerContext, bindingContext)
gets invoked. Everything ok, but. How do I get property attributes from controller/bindingContext, to parse my date correctly? How can I get to the PropertyDesciptor
of property Birth
?
Because of separation of concerns my model class is defined in an assembly that doesn't (and shouldn't) reference System.Web.MVC assembly. Setting custom binding (similar to Scott Hanselman's example) attributes is a no-go here.
you can change the default model binder to use the user culture using IModelBinder
public class DateTimeBinder : IModelBinder
{
public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
var value = bindingContext.ValueProvider.GetValue(bindingContext.ModelName);
bindingContext.ModelState.SetModelValue(bindingContext.ModelName, value);
return value.ConvertTo(typeof(DateTime), CultureInfo.CurrentCulture);
}
}
public class NullableDateTimeBinder : IModelBinder
{
public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
var value = bindingContext.ValueProvider.GetValue(bindingContext.ModelName);
bindingContext.ModelState.SetModelValue(bindingContext.ModelName, value);
return value == null
? null
: value.ConvertTo(typeof(DateTime), CultureInfo.CurrentCulture);
}
}
And in the Global.Asax add the following to Application_Start():
ModelBinders.Binders.Add(typeof(DateTime), new DateTimeBinder());
ModelBinders.Binders.Add(typeof(DateTime?), new NullableDateTimeBinder());
Read more at this excellent blog that describe why Mvc framework team implemented a default Culture to all users.