He tenido el mismo problema con formato de fecha corta unión a DateTime del modelo . Después de ver muchos ejemplos diferentes (no sólo en relación con DateTime) pongo juntos los siguientes aparatos:
using System;
using System.Globalization;
using System.Web.Mvc;
namespace YourNamespaceHere
{
public class CustomDateBinder : IModelBinder
{
public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
if (controllerContext == null)
throw new ArgumentNullException("controllerContext", "controllerContext is null.");
if (bindingContext == null)
throw new ArgumentNullException("bindingContext", "bindingContext is null.");
var value = bindingContext.ValueProvider.GetValue(bindingContext.ModelName);
if (value == null)
throw new ArgumentNullException(bindingContext.ModelName);
CultureInfo cultureInf = (CultureInfo)CultureInfo.CurrentCulture.Clone();
cultureInf.DateTimeFormat.ShortDatePattern = "dd/MM/yyyy";
bindingContext.ModelState.SetModelValue(bindingContext.ModelName, value);
try
{
var date = value.ConvertTo(typeof(DateTime), cultureInf);
return date;
}
catch (Exception ex)
{
bindingContext.ModelState.AddModelError(bindingContext.ModelName, ex);
return null;
}
}
}
public class NullableCustomDateBinder : IModelBinder
{
public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
if (controllerContext == null)
throw new ArgumentNullException("controllerContext", "controllerContext is null.");
if (bindingContext == null)
throw new ArgumentNullException("bindingContext", "bindingContext is null.");
var value = bindingContext.ValueProvider.GetValue(bindingContext.ModelName);
if (value == null) return null;
CultureInfo cultureInf = (CultureInfo)CultureInfo.CurrentCulture.Clone();
cultureInf.DateTimeFormat.ShortDatePattern = "dd/MM/yyyy";
bindingContext.ModelState.SetModelValue(bindingContext.ModelName, value);
try
{
var date = value.ConvertTo(typeof(DateTime), cultureInf);
return date;
}
catch (Exception ex)
{
bindingContext.ModelState.AddModelError(bindingContext.ModelName, ex);
return null;
}
}
}
}
Para mantener con la forma en que las rutas etc se regiseterd en el archivo global ASAX También he añadido una nueva clase sytatic a la App_Start carpeta de mi proyecto llamado MVC4 CustomModelBinderConfig:
using System;
using System.Web.Mvc;
namespace YourNamespaceHere
{
public static class CustomModelBindersConfig
{
public static void RegisterCustomModelBinders()
{
ModelBinders.Binders.Add(typeof(DateTime), new CustomModelBinders.CustomDateBinder());
ModelBinders.Binders.Add(typeof(DateTime?), new CustomModelBinders.NullableCustomDateBinder());
}
}
}
me llamo entonces sólo los RegisterCustomModelBinders estáticas de mi Global ASASX Application_Start así:
protected void Application_Start()
{
/* bla blah bla the usual stuff and then */
CustomModelBindersConfig.RegisterCustomModelBinders();
}
Una nota importante aquí es que si se escribe un valor DateTime a un HiddenField así:
@Html.HiddenFor(model => model.SomeDate) // a DateTime property
@Html.Hiddenfor(model => model) // a model that is of type DateTime
Lo hice y el valor real de la página estaba en el formato "MM hh/dd/aaaa: mm: ss tt "en lugar de" dd/MM/aaaa hh: mm: ss tt "como yo quería. Esto causó que mi validación de modelo fallara o devolviera la fecha incorrecta (obviamente intercambiando los valores de día y mes).
Después de una gran cantidad de rascarse la cabeza y los intentos fallidos La solución fue establecer la información de cultivo para cada petición al hacer esto en el Global.asax:
protected void Application_BeginRequest()
{
CultureInfo cInf = new CultureInfo("en-ZA", false);
// NOTE: change the culture name en-ZA to whatever culture suits your needs
cInf.DateTimeFormat.DateSeparator = "/";
cInf.DateTimeFormat.ShortDatePattern = "dd/MM/yyyy";
cInf.DateTimeFormat.LongDatePattern = "dd/MM/yyyy hh:mm:ss tt";
System.Threading.Thread.CurrentThread.CurrentCulture = cInf;
System.Threading.Thread.CurrentThread.CurrentUICulture = cInf;
}
No funcionará si usted se pega en Application_Start o incluso Session_Start desde que lo asigna al hilo actual de la sesión. Como bien sabe, las aplicaciones web son apátridas, por lo que el hilo que atendió su solicitud previamente es del mismo hilo que atiende su solicitud actual, por lo tanto, su información cultural ha pasado al gran GC en el cielo digital.
agradecimiento a: Ivan Zlatev - http://ivanz.com/2010/11/03/custom-model-binding-using-imodelbinder-in-asp-net-mvc-two-gotchas/
garik - https://stackoverflow.com/a/2468447/578208
Dmitry - https://stackoverflow.com/a/11903896/578208
Hey .. Sólo cambia la fecha del sistema formato- DD/MM/AAAA a DD/MM/aaaa y lo ha hecho. También tengo el mismo problema, lo resolví cambiando el formato de fecha del sistema. – banny
@banny si la aplicación es global y podría ser que cada uno no tiene el mismo formato de fecha y hora, ¿cómo podría hacerlo? , no debes ir y cambiar cada fecha y hora Formato. –
Ninguna de estas respuestas me está ayudando. La forma necesita ser localizada. Algunos usuarios pueden tener la fecha de una manera, otros a la inversa. Configurando algo en la web.config. o global.asax no va a ayudar. Seguiré buscando una mejor respuesta, pero una de ellas sería tratar la fecha como una cadena hasta que regrese a C#. – astrosteve