MVC4的DataType.Date EditorFor不会显示在Chrome中的date值,在Internet Explorer罚款

我在我的模型上使用DataType.Date属性,在我的视图中使用EditorFor。 这在Internet Explorer 8和Internet Explorer 9中工作正常,但在Google Chrome中显示的是dateselect器,而不是显示该值,只是以褪色的灰色文本显示“月/日/年”。

Google Chrome为什么不显示该值?

模型:

[DataType(DataType.Date)] public Nullable<System.DateTime> EstPurchaseDate { get; set; } 

视图:

 <td class="fieldLabel">Est. Pur. Date</td> <td class="field">@Html.EditorFor(m=>m.EstPurchaseDate)</td> 

铬

IE浏览器

当使用[DataType(DataType.Date)]装饰模型属性时,ASP.NET MVC 4中的默认模板将生成type="date"的input字段:

 <input class="text-box single-line" data-val="true" data-val-date="The field EstPurchaseDate must be a date." id="EstPurchaseDate" name="EstPurchaseDate" type="date" value="9/28/2012" /> 

支持HTML5(例如Google Chrome)的浏览器使用dateselect器呈现此input字段。

为了正确显示date,该值必须格式化为2012-09-28 。 来自规格的报价:

value(值): [RFC 3339]中定义的有效全date,以及年分量为四位或四位以上代表大于0的数字的附加条件。

您可以使用DisplayFormat属性强制执行此格式:

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

在MVC5.2中,将Date.cshtml添加到文件夹〜/ Views / Shared / EditorTemplates:

 @model DateTime? @{ IDictionary<string, object> htmlAttributes; object objAttributes; if (ViewData.TryGetValue("htmlAttributes", out objAttributes)) { htmlAttributes = objAttributes as IDictionary<string, object> ?? 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) } 

作为Darin Dimitrov的回答的补充:

如果你只想要这个特定的行使用某种(不同于标准的)格式,你可以在MVC5中使用:

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

在MVC 3中,我不得不补充:

 using System.ComponentModel.DataAnnotations; 

在添加属性时使用:

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

特别是如果你像我这样在.edmx文件中添加这些属性。 我发现默认.edmx文件没有这个使用,所以只添加propeties是不够的。

如果从模型中删除[DataType(DataType.Date)] ,则Chrome中的input字段将呈现为type="datetime"并且不会显示datepicker。

我仍然有一个问题,通过格式yyyy-MM-dd,但我通过更改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" }) } 

回复MVC4的DataType.Date EditorFor将不会在Chrome中显示date值,在IE中罚款

在模型中,您需要具有以下types的声明:

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

要么

 [DataType(DataType.Date)] public Nullable<System.DateTime> DateXYZ { get; set; } 

您不需要使用以下属性:

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

在Date.cshtml使用这个模板:

 @model Nullable<DateTime> @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" }) } } 

玩的开心! 问候,Blerton

如果你需要控制date的格式(换句话说,不只是yyyy-mm-dd格式是可接受的),另一种解决scheme可能是添加一个types为string的助手属性,并添加一个datevalidation器到该属性,并在用户界面上绑定到这个属性。

  [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"); } } 

这里是一个datevalidation器:

 [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; } }