MVC4 DataType.Date EditorFür die Anzeige des Datumswerts in Chrome wird in Internet Explorer nicht angezeigt

198

Ich verwende das DataType.Date-Attribut für mein Modell und ein EditorFor in meiner Ansicht. Dies funktioniert in Internet Explorer 8 und Internet Explorer 9 einwandfrei. In Google Chrome wird jedoch eine Datumsauswahl angezeigt. Statt des Werts wird nur "Monat / Tag / Jahr" in ausgeblendetem grauem Text angezeigt.

Warum wird der Wert in Google Chrome nicht angezeigt?

Modell:

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

Aussicht:

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

Chrom

Internet Explorer

Ben Finkel
quelle

Antworten:

377

Wenn Sie eine Modelleigenschaft mit [DataType(DataType.Date)]der Standardvorlage in ASP.NET MVC 4 dekorieren, wird ein Eingabefeld generiert mit 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" />

Browser, die HTML5 wie Google Chrome unterstützen, rendern dieses Eingabefeld mit einer Datumsauswahl.

Um das Datum korrekt anzuzeigen, muss der Wert als formatiert sein 2012-09-28. Zitat aus der Spezifikation :

value: Ein gültiges Volldatum gemäß Definition in [RFC 3339] mit der zusätzlichen Qualifikation, dass die Jahreskomponente vier oder mehr Ziffern umfasst, die eine Zahl größer als 0 darstellen.

Sie können dieses Format mithilfe des folgenden DisplayFormatAttributs erzwingen :

[DataType(DataType.Date)]
[DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)]
public Nullable<System.DateTime> EstPurchaseDate { get; set; }
Darin Dimitrov
quelle
44
Darin danke, das war perfekt! Du hast in den letzten zwei Jahren so viele meiner MVC-Fragen beantwortet, du rockst!
Ben Finkel
3
Tolle Antwort, aber ich finde das ansprechend. Sie müssen es erzwingen, damit die Steuerung richtig funktioniert!
Coops
7
Was wäre die Art und Weise, dies "global" für alle markierten Eigenschaften zu [DataType(DataType.Date)]tun, damit ich nicht alle diese Eigenschaften separat markieren müsste, mit dem Risiko, einige zu verpassen?
Marjan Venema
7
Darin, was können wir Menschen außerhalb der USA tun? Wie kann ich den Spezifikationswert festlegen, aber ein benutzerdefiniertes Datumsformat anzeigen? dh UK?
Piotr Kula
3
@ MarjanVenema- Ich habe den "ExtensibleModelMetadataProvider" von Matt Honeycutt's FailTracker ( github.com/MattHoneycutt/Fail-Tracker ) verwendet. Suchen Sie unter dem Infrastrukturordner nach den ModelMetadata. Ich habe diese Klassen verwendet und dann eine Filterimplementierung von IModelMetadataFilter erstellt. Wenn die TransformMetadata-Methode aufgerufen wird, können Sie die Eigenschaften "DisplayFormatString" und "EditFormatString" der Metadaten bearbeiten. Ich hoffe, das bringt dich in die richtige Richtung (übrigens gibt es ein großartiges Pluralsight-Video, das Fail-Tracker verwendet)
SwampyFox
44

Fügen Sie in MVC5.2 Date.cshtml zum Ordner ~ / Views / Shared / EditorTemplates hinzu:

@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)
}
Charlie
quelle
Vielen Dank! behebt das erwähnte Chrome "Problem" und natürlich können Sie ein anderes Anzeigeformat für Ihre datetime Eigenschaft haben!
cmxl
Ja tolle Lösung. Dies bietet eine hervorragende Lösung für diejenigen von uns, die nicht in den USA sind.
Richard McKenna
Ich denke, dies ist die beste Lösung für das Problem. Es behebt nur das Editorproblem und hat keinen Einfluss auf die vorhandene Formatierung der Anzeige.
Dsghi
1
Die Verwendung von "Date.cshtml" anstelle von "DateTime.cshtml" war die magische Antwort! Es funktioniert auch in MVC 4.
Atron Seige
Toll! Obrigado.
Guilherme de Jesus Santos
16

Als Ergänzung zu Darin Dimitrovs Antwort:

Wenn Sie nur möchten, dass diese bestimmte Zeile ein bestimmtes (vom Standard abweichendes) Format verwendet, können Sie in MVC5 Folgendes verwenden:

@Html.EditorFor(model => model.Property, new {htmlAttributes = new {@Value = @Model.Property.ToString("yyyy-MM-dd"), @class = "customclass" } })
Arjan
quelle
Wie @am Anfang, @Value = @Model.Property...braucht das das noch @? Meinst du nur new { Value = Model.Property...?
user3454439
11

In MVC 3 musste ich hinzufügen:

using System.ComponentModel.DataAnnotations;

unter den Verwendungen beim Hinzufügen von Eigenschaften:

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

Vor allem, wenn Sie diese Eigenschaften wie ich in eine .edmx-Datei einfügen. Ich habe festgestellt, dass .edmx-Dateien diese Funktion standardmäßig nicht verwenden, sodass das Hinzufügen von nur Eigenschaften nicht ausreicht.

Azoro
quelle
10

Wenn Sie [DataType(DataType.Date)]aus Ihrem Modell entfernen , wird das Eingabefeld in Chrome als gerendert type="datetime"und zeigt auch nicht die Datumsauswahl an.

bernieb
quelle
Danke Bernie. Ich hatte nicht so viele Probleme mit der Anzeige des Pickers wie mit den Daten, die nicht in das Eingabefeld eingegeben wurden. Das ist aber gut zu wissen.
Ben Finkel
Opera rendert jedoch einen Datepicker. Verwenden Sie modernizr, um einige Polyfill
Cleftheris
1
Wenn es ein Datum sein soll, sollte es als Eingabe vom Typ gerendert werden date. Die Verwendung datetimeals Workaround ist unangemessen, da die Daten nicht semantisch dargestellt werden.
Chris Pratt
4

Ich hatte immer noch ein Problem damit, das Format JJJJ-MM-TT zu übergeben, aber ich habe es umgangen, indem ich die Datei Date.cshtml geändert habe:

@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"  })
}
markpcasey
quelle
danke schließlich das funktioniert, habe ich versucht string.Format("{0}/{1}/{2}")zu bekommen dd/mm/yyyyFormat, und es funktioniert gut, i Datenbank erste Methode verwendet , aber Displayformat , weiß nicht , warum , wenn ?, sowieso jemand versuchen brauchte nicht mit partieller Klasse arbeitete diese Methode, i didn‘
Ich
3

Antwort auf MVC4 DataType.Date EditorFor zeigt in Chrome keinen Datumswert an, in IE in Ordnung

Im Modell müssen Sie folgende Art von Deklaration haben:

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

ODER

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

Sie müssen das folgende Attribut nicht verwenden:

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

Verwenden Sie in der Datei Date.cshtml diese Vorlage:

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

Habe Spaß! Grüße, Blerton

Blerton Hoxha
quelle
Wenn Sie dies auf diese Weise tun, gibt Ihnen Chrome keine Datumsauswahl. Ich verwende Ihre Lösung, ändere sie jedoch so, dass 1) ich das DisplayFormatAttribut verwende 2) den Test ändere, um zu überprüfen, ob der Browsertyp Chrome ist, und dann @Html.EditorFor(m=>m.EstPurchaseDate)3) sonst mache @Html.TextBox("EstPurchaseDate", dt.ToString("MM/dd/yyyy"))Hinweis: Bei # 2 wäre eine bessere Überprüfung, wenn Der Browser versteht HTML5, aber ich weiß nicht, wie das geht.
David
4
Downvoting zur Browsererkennung im serverseitigen Code.
Tetsujin no Oni
1

Wenn Sie die Kontrolle über das Format des Datums haben müssen (mit anderen Worten, nicht nur das Format JJJJ-MM-TT ist akzeptabel), können Sie auch eine Hilfseigenschaft vom Typ Zeichenfolge hinzufügen und dieser Eigenschaft einen Datumsvalidator hinzufügen und binden Sie an diese Eigenschaft auf der Benutzeroberfläche.

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

Und hier ist ein Datumsvalidator:

[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;
    }
}
Martin Staufcik
quelle