MVC4 DataType.Date EditorFor sẽ không hiển thị giá trị ngày trong Chrome, tốt trong Internet Explorer


198

Tôi đang sử dụng thuộc tính DataType.Date trên mô hình của mình và EditorFor trong chế độ xem của tôi. Điều này hoạt động tốt trong Internet Explorer 8Internet Explorer 9 , nhưng trong Google Chrome, nó đang hiển thị trình chọn ngày và thay vì hiển thị giá trị, nó chỉ hiển thị "Tháng / Ngày / Năm" bằng văn bản màu xám mờ.

Tại sao Google Chrome không hiển thị giá trị?

Mô hình:

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

Lượt xem:

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

Trình duyệt Chrome

trình duyệt web IE

Câu trả lời:


377

Khi bạn trang trí một thuộc tính mô hình bằng [DataType(DataType.Date)]mẫu mặc định trong ASP.NET MVC 4 sẽ tạo trường nhập type="date":

<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" />

Các trình duyệt hỗ trợ HTML5 như Google Chrome sẽ hiển thị trường nhập này bằng công cụ chọn ngày.

Để hiển thị chính xác ngày, giá trị phải được định dạng là 2012-09-28. Trích dẫn từ đặc điểm kỹ thuật :

value: Một ngày đầy đủ hợp lệ như được định nghĩa trong [RFC 3339], với tiêu chuẩn bổ sung rằng thành phần năm là bốn hoặc nhiều chữ số đại diện cho một số lớn hơn 0.

Bạn có thể thực thi định dạng này bằng cách sử dụng DisplayFormatthuộc tính:

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

44
Darin cảm ơn bạn, đó là hoàn hảo! Bạn đã trả lời rất nhiều câu hỏi MVC của tôi trong hai năm qua, bạn thật tuyệt!
Ben Finkel

3
Câu trả lời tuyệt vời nhưng tôi cảm thấy điều này hấp dẫn bạn phải buộc nó chỉ để có được sự kiểm soát để hoạt động đúng!
Coops

7
Điều gì sẽ là cách thực hiện "toàn cầu" này cho tất cả các thuộc tính được đánh dấu [DataType(DataType.Date)]để tôi không phải đánh dấu tất cả các thuộc tính này một cách riêng biệt với nguy cơ thiếu một số?
Marjan Venema

7
Darin, những người bên ngoài Hoa Kỳ chúng ta có thể làm gì? Làm cách nào tôi có thể đặt giá trị đặc tả nhưng hiển thị định dạng ngày tùy chỉnh? tức là nước Anh?
Piotr Kula

3
@ MarjanVenema- Tôi đã sử dụng "ExtensibleModelMetadataProvider" từ FailTracker của Matt Honeycutt ( github.com/MattHoneycutt/Fail-Tracker ). Xem trong Thư mục cơ sở hạ tầng để ModelMetadata. Tôi đã sử dụng các lớp đó và sau đó tạo một triển khai bộ lọc của IModelMetadataFilter. Khi phương thức TransformMetadata được gọi, sau đó bạn có thể chỉnh sửa các thuộc tính "DisplayFormatString" và "EditFormatString" của siêu dữ liệu. Hy vọng điều này sẽ giúp bạn đi đúng hướng (btw, có một video tuyệt vời sử dụng Fail-Tracker)
SwampyFox

44

Trong MVC5.2, thêm Date.cshtml vào thư mục ~ / Lượt xem / Chia sẻ / Trình soạn thảo:

@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)
}

cảm ơn! khắc phục "sự cố" chrome đã đề cập và tất nhiên bạn có thể có một dạng hiển thị khác trên thuộc tính datetime của mình!
cmxl

Có giải pháp tuyệt vời. Điều này cung cấp một công việc tuyệt vời xung quanh cho những người trong chúng ta không ở Mỹ.
Richard McKenna

Tôi nghĩ rằng đây là giải pháp tốt nhất cho sự cố, nó chỉ khắc phục sự cố trình chỉnh sửa và không ảnh hưởng đến định dạng hiển thị hiện có.
DSghi

1
Sử dụng "Date.cshtml" thay vì "DateTime.cshtml" là câu trả lời kỳ diệu! Nó hoạt động trong MVC 4 là tốt.
Atron Seige

Tuyệt quá! Obrigado.
Guilherme de Jesus Santos

16

Như một bổ sung cho câu trả lời của Darin Dimitrov:

Nếu bạn chỉ muốn dòng cụ thể này sử dụng một định dạng nhất định (khác với tiêu chuẩn), bạn có thể sử dụng trong MVC5:

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

Như có @lúc ban đầu, mà @Value = @Model.Property...vẫn cần điều đó @? Ý bạn là new { Value = Model.Property...sao?
dùng3454439

11

Trong MVC 3 tôi đã phải thêm:

using System.ComponentModel.DataAnnotations;

trong số các cách sử dụng khi thêm thuộc tính:

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

Đặc biệt nếu bạn đang thêm các thuộc tính này trong tệp .edmx như tôi. Tôi thấy rằng theo mặc định, các tệp .edmx không có điều này bằng cách sử dụng nên chỉ thêm các thủ tục là không đủ.


10

Nếu bạn xóa [DataType(DataType.Date)]khỏi mô hình của mình, trường đầu vào trong Chrome sẽ được hiển thị dưới dạng type="datetime"và sẽ không hiển thị trình đo ngày.


Cảm ơn Bernie. Tôi không gặp rắc rối với trình chọn hiển thị khi tôi có dữ liệu không được đưa vào hộp nhập. Điều này là tốt để biết mặc dù.
Ben Finkel

Opera làm cho một người hẹn hò mặc dù. Sử dụng Modernizr để thực hiện một số polyfill
cleftheris

1
Nếu nó được coi là một ngày, nó sẽ được hiển thị dưới dạng đầu vào của loại date. Sử dụng datetimenhư một công việc xung quanh là không phù hợp, vì nó không đại diện cho dữ liệu.
Chris Pratt

4

Tôi vẫn gặp sự cố với việc chuyển định dạng yyyy-MM-dd, nhưng tôi đã khắc phục bằng cách thay đổi 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"  })
}

cảm ơn bạn cuối cùng đã làm việc, tôi đã cố gắng string.Format("{0}/{1}/{2}")để có được dd/mm/yyyyđịnh dạng và nó hoạt động tốt, tôi đã sử dụng phương pháp cơ sở dữ liệu đầu tiên nhưng DisplayFormat không hoạt động với một phần lớp, không biết tại sao?, dù sao thì bất cứ ai nếu cần thử phương pháp này , tôi đã không Hãy thử nhưng nếu có ai cần, hy vọng nó có ích
shaijut 30/03/2015

3

Trả lời MVC4 DataType.Date EditorFor sẽ không hiển thị giá trị ngày trong Chrome, tốt trong IE

Trong Mô hình, bạn cần có loại khai báo sau:

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

HOẶC LÀ

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

Bạn không cần sử dụng thuộc tính sau:

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

Tại Date.cshtml sử dụng mẫu này:

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

Chúc vui vẻ! Trân trọng, Blerton


Nếu bạn làm theo cách này, Chrome sẽ không cung cấp cho bạn công cụ chọn ngày. Tôi đang sử dụng giải pháp của bạn, nhưng sửa đổi để 1) Tôi sử dụng DisplayFormatthuộc tính 2) Thay đổi kiểm tra để kiểm tra xem loại trình duyệt có phải là chrome không, sau đó thực hiện @Html.EditorFor(m=>m.EstPurchaseDate)3) Khác @Html.TextBox("EstPurchaseDate", dt.ToString("MM/dd/yyyy")): Lưu ý: trên # 2, kiểm tra tốt hơn sẽ là nếu trình duyệt hiểu HTML5, nhưng tôi không biết làm thế nào để làm điều đó.
David

4
Downvote để phát hiện trình duyệt trong mã phía máy chủ.
Tetsujin no Oni

1

Nếu bạn cần kiểm soát định dạng của ngày (nói cách khác, không chỉ định dạng yyyy-mm-dd có thể chấp nhận được), một giải pháp khác có thể là thêm thuộc tính của trình trợ giúp thuộc loại chuỗi và thêm trình xác thực ngày vào thuộc tính đó và liên kết với tài sản này trên UI.

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

Và đây là một trình xác nhận ngày:

[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;
    }
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.