MVC4 DataType.Date EditorЗабо не відображатиме значення дати в Chrome, добре в Internet Explorer


198

Я використовую атрибут DataType.Date для своєї моделі та редакторFor, на мій погляд. Це добре працює в Internet Explorer 8 та Internet Explorer 9 , але в Google Chrome він відображає інструмент вибору дати, а замість того, щоб відображати значення, він просто відображає "Місяць / день / рік" у відцвілому сірому тексті.

Чому 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>

Хром

Internet Explorer

Відповіді:


377

Коли ви прикрашаєте властивість моделі [DataType(DataType.Date)]шаблоном за замовчуванням у ASP.NET, MVC 4 генерує поле введення 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" />

Веб-переглядачі, які підтримують HTML5, такий Google Chrome надають це поле для введення за допомогою вибору дати.

Щоб правильно відобразити дату, значення слід відформатувати як 2012-09-28. Цитата із специфікації :

значення: Дійсна повна дата, визначена в [RFC 3339], з додатковою кваліфікацією, що компонент року становить чотири або більше цифр, що представляють число, що перевищує 0.

Ви можете застосувати цей формат за допомогою DisplayFormatатрибута:

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

44
Дарин дякую, це було ідеально! Ви відповіли на стільки моїх запитань MVC протягом останніх двох років, рок!
Бен Фінкель

3
Чудова відповідь, але я вважаю, що це привабливо, ви повинні змусити його просто змусити управління працювати належним чином!
Купи

7
Який би спосіб зробити це "у всьому світі" для всіх властивостей, позначених [DataType(DataType.Date)]таким чином, щоб мені не довелося позначати всі ці властивості окремо, ризикуючи пропустити деякі?
Мар'ян Венема

7
Дарин, що нам можуть робити люди за межами США? Як я можу встановити значення специфікації, але відобразити власний формат дати? тобто Великобританія?
Пьотр Кула

3
@ MarjanVenema- Я використав "ExtensibleModelMetadataProvider" від FailTracker Метта Хонікотта ( github.com/MattHoneycutt/Fail-Tracker ). Подивіться під папкою інфраструктури до ModelMetadata. Я використовував ці класи, а потім створив реалізацію фільтру IModelMetadataFilter. Коли викликається метод TransformMetadata, ви можете змінити властивості "DisplayFormatString" та "EditFormatString" метаданих. Сподіваюсь, це приведе вас у правильний бік (btw, є чудове відео з множинністю, яке використовує Fail-Tracker)
SwampyFox

44

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

Дякую! виправляє згаданий хромований "випуск", і, звичайно, у вас може бути інший формат дисплея у вашій власності дати!
cmxl

Так, чудове рішення. Це забезпечує чудову роботу для тих, хто не перебуває у США.
Річард Маккенна

Я думаю, що це найкраще рішення проблеми, воно виправляє лише проблему редактора і не впливає на існуюче форматування дисплея.
dsghi

1
Магічною відповіддю стало використання "Date.cshtml" замість "DateTime.cshtml"! Він працює і в MVC 4.
Атрон Сейдж

Чудово! Обрігадо.
Гільгерме де Ісус Сантос

16

Як додаток до відповіді Даріна Димитрова:

Якщо ви хочете, щоб цей конкретний рядок використовував певний (відмінний від стандартного) формат, ви можете використовувати в MVC5:

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

Як є @на початку, що @Value = @Model.Property...ще потрібно це @? Ви маєте на увазі просто new { Value = Model.Property...?
user3454439

11

У MVC 3 мені довелося додати:

using System.ComponentModel.DataAnnotations;

серед прийомів при додаванні властивостей

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

Особливо, якщо ви додаєте ці властивості у файл .edmx, як я. Я виявив, що за замовчуванням у файлах .edmx цього немає, тому додавання лише властивостей недостатньо.


10

Якщо ви вилучите [DataType(DataType.Date)]зі своєї моделі, поле введення в Chrome відображається як type="datetime"і не відображатиме підбирача дат.


Дякую Берні У мене не було таких проблем із вибором вибору, як і з тим, що дані не вводяться у поле введення. Це добре знати, хоча.
Бен Фінкель

Хоча Opera надає підбірника побачень. Використовуйте модернізатор, щоб зробити кілька
поліфілів

1
Якщо це повинна бути дата, вона повинна бути відображена як введення типу date. Використовувати datetimeяк обхідне рішення недоцільно, оскільки воно не представляє семантично даних.
Кріс Пратт

4

У мене все-таки виникли проблеми з передачею формату "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"  })
}

спасибі , нарешті , це працювало, я намагався string.Format("{0}/{1}/{2}")отримати dd/mm/yyyyформат, і він працює відмінно, я використовував бази даних першого метод , але DisplayFormat не працювала з розділяються класом, не знаю , чому?, в будь-якому випадку хто - небудь , якщо це необхідно спробувати цей метод, я Didn » не спробуйте, але якщо комусь потрібно, сподівайтеся, що це допоможе
shaijut

3

Відповідь на редактор MVC4 DataType.Date EdFor не відображатиме значення дати в Chrome, добре в IE

У Моделі потрібно мати такий тип декларації:

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

Весело! З повагою, Блертон


Якщо ви зробите це таким чином, Chrome не надасть вам вибору дати. Я використовую ваше рішення, але видозмінюючи так, щоб 1) Я використовував DisplayFormatатрибут 2) Змінював тест, щоб перевірити, чи тип браузера є хромованим, потім зробіть @Html.EditorFor(m=>m.EstPurchaseDate)3) Ще потрібно @Html.TextBox("EstPurchaseDate", dt.ToString("MM/dd/yyyy"))Примітка: на # 2, краще перевірити, якщо браузер розуміє HTML5, але я не знаю, як це зробити.
Девід

4
Націлювання на виявлення браузера в коді з боку сервера.
Tetsujin no Oni

1

Якщо вам потрібно мати контроль над форматом дати (іншими словами, прийнятний не лише формат yyyy-mm-dd), іншим рішенням може бути додавання хелперного властивості типу рядка та додавання валідатора дати до цього властивості , і прив’язати до цього ресурсу в інтерфейсі користувача.

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

Ось валідатор дати:

[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;
    }
}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.