MVC4 DataType.Date EditorFor no mostrará el valor de la fecha en Chrome, bien en Internet Explorer

Estoy usando el atributo DataType.Date en mi modelo y un EditorFor en mi opinión. Esto funciona bien en Internet Explorer 8 e Internet Explorer 9 , pero en Google Chrome muestra un selector de fecha y en lugar de mostrar el valor, solo muestra “Mes / Día / Año” en un texto gris desteñido.

¿Por qué Google Chrome no mostrará el valor?

Modelo:

[DataType(DataType.Date)] public Nullable EstPurchaseDate { get; set; } 

Ver:

 Est. Pur. Date @Html.EditorFor(m=>m.EstPurchaseDate) 

Cromo

explorador de Internet

Cuando decora una propiedad de modelo con [DataType(DataType.Date)] la plantilla predeterminada en ASP.NET MVC 4 genera un campo de entrada de type="date" :

  

Los navegadores compatibles con HTML5 como Google Chrome representan este campo de entrada con un selector de fecha.

Para mostrar correctamente la fecha, el valor debe formatearse como 2012-09-28 . Cita de la especificación :

valor: una fecha completa válida como se define en [RFC 3339], con la calificación adicional de que el componente del año tiene cuatro o más dígitos que representan un número mayor que 0.

Puede aplicar este formato utilizando el atributo DisplayFormat :

 [DataType(DataType.Date)] [DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)] public Nullable EstPurchaseDate { get; set; } 

En MVC5.2, agregue Date.cshtml a la carpeta ~ / Views / Shared / EditorTemplates:

 @model DateTime? @{ IDictionary htmlAttributes; object objAttributes; if (ViewData.TryGetValue("htmlAttributes", out objAttributes)) { htmlAttributes = objAttributes as IDictionary ?? HtmlHelper.AnonymousObjectToHtmlAttributes(objAttributes); } else { htmlAttributes = new RouteValueDictionary(); } htmlAttributes.Add("type", "date"); String format = (Request.UserAgent != null && Request.UserAgent.Contains("Chrome")) ? "{0:yyyy-MM-dd}" : "{0:d}"; @Html.TextBox("", Model, format, htmlAttributes) } 

Como una adición a la respuesta de Darin Dimitrov:

Si solo desea que esta línea en particular use un formato determinado (diferente del estándar), puede usar en MVC5:

 @Html.EditorFor(model => model.Property, new {htmlAttributes = new {@Value = @Model.Property.ToString("yyyy-MM-dd"), @class = "customclass" } }) 

En MVC 3 tuve que agregar:

 using System.ComponentModel.DataAnnotations; 

entre los usuarios al agregar propiedades:

 [DataType(DataType.Date)] [DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)] 

Especialmente si está agregando estas propiedades en un archivo .edmx como yo. Descubrí que, por defecto, los archivos .edmx no tienen este uso, por lo que no es suficiente agregar solo propenetas.

Si elimina [DataType(DataType.Date)] de su modelo, el campo de entrada en Chrome se representa como type="datetime" y tampoco mostrará el datepicker.

Todavía tenía un problema al pasar el formato aaaa-MM-dd, pero lo solucioné cambiando el Date.cshtml:

 @model DateTime? @{ string date = string.Empty; if (Model != null) { date = string.Format("{0}-{1}-{2}", Model.Value.Year, Model.Value.Month, Model.Value.Day); } @Html.TextBox(string.Empty, date, new { @class = "datefield", type = "date" }) } 

Responda a MVC4 DataType.Date EditorFor no mostrará el valor de la fecha en Chrome, bien en IE

En el Modelo necesita tener el siguiente tipo de statement:

 [DataType(DataType.Date)] public DateTime? DateXYZ { get; set; } 

O

 [DataType(DataType.Date)] public Nullable DateXYZ { get; set; } 

No necesita usar el siguiente atributo:

 [DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)] 

En Date.cshtml usa esta plantilla:

 @model Nullable @using System.Globalization; @{ DateTime dt = DateTime.Now; if (Model != null) { dt = (System.DateTime)Model; } if (Request.Browser.Type.ToUpper().Contains("IE") || Request.Browser.Type.Contains("InternetExplorer")) { @Html.TextBox("", String.Format("{0:d}", dt.ToShortDateString()), new { @class = "datefield", type = "date" }) } else { //Tested in chrome DateTimeFormatInfo dtfi = CultureInfo.CreateSpecificCulture("en-US").DateTimeFormat; dtfi.DateSeparator = "-"; dtfi.ShortDatePattern = @"yyyy/MM/dd"; @Html.TextBox("", String.Format("{0:d}", dt.ToString("d", dtfi)), new { @class = "datefield", type = "date" }) } } 

¡Que te diviertas! Saludos, Blerton

Si necesita tener control sobre el formato de la fecha (en otras palabras, no solo es aceptable el formato aaaa-mm-dd), otra solución podría ser agregar una propiedad auxiliar que sea de tipo cadena y agregar un validador de fecha a esa propiedad y se une a esta propiedad en la interfaz de usuario.

  [Display(Name = "Due date")] [Required] [AllowHtml] [DateValidation] public string DueDateString { get; set; } public DateTime? DueDate { get { return string.IsNullOrEmpty(DueDateString) ? (DateTime?)null : DateTime.Parse(DueDateString); } set { DueDateString = value == null ? null : value.Value.ToString("d"); } } 

Y aquí hay un validador de fecha:

 [AttributeUsage(AttributeTargets.Property, AllowMultiple = true, Inherited = true)] public class DateValidationAttribute : ValidationAttribute { public DateValidationAttribute() { } protected override ValidationResult IsValid(object value, ValidationContext validationContext) { if (value != null) { DateTime date; if (value is string) { if (!DateTime.TryParse((string)value, out date)) { return new ValidationResult(validationContext.DisplayName + " must be a valid date."); } } else date = (DateTime)value; if (date < new DateTime(1900, 1, 1) || date > new DateTime(3000, 12, 31)) { return new ValidationResult(validationContext.DisplayName + " must be a valid date."); } } return null; } }