MVC4 DataType.Date Editor Per non visualizzare il valore della data in Chrome, bene in Internet Explorer


198

Sto usando l'attributo DataType.Date sul mio modello e un EditorFor a mio avviso. Funziona bene in Internet Explorer 8 e Internet Explorer 9 , ma in Google Chrome mostra un selettore di date e invece di visualizzare il valore visualizza solo "Mese / Giorno / Anno" in testo grigio sbiadito.

Perché Google Chrome non visualizzerà il valore?

Modello:

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

Visualizza:

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

Cromo

Internet Explorer

Risposte:


377

Quando si decora una proprietà del modello con [DataType(DataType.Date)]il modello predefinito in ASP.NET MVC 4 genera un campo di input di 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" />

I browser che supportano HTML5 come Google Chrome visualizzano questo campo di input con un selettore di date.

Per visualizzare correttamente la data, il valore deve essere formattato come 2012-09-28. Citazione dalla specifica :

valore: una data intera valida come definita in [RFC 3339], con la qualifica aggiuntiva che la componente dell'anno è composta da quattro o più cifre che rappresentano un numero maggiore di 0.

È possibile applicare questo formato utilizzando l' DisplayFormatattributo:

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

44
Darin grazie, è stato perfetto! Hai risposto a molte delle mie domande MVC negli ultimi due anni, rock!
Ben Finkel,

3
Ottima risposta ma ritengo che questo sia interessante, devi forzarlo solo per far funzionare correttamente il controllo!
Coops

7
Quale sarebbe il modo di fare questo "a livello globale" per tutte le proprietà contrassegnate in [DataType(DataType.Date)]modo da non dover contrassegnare tutte queste proprietà separatamente con il rischio di perderne alcune?
Marjan Venema,

7
Darin, cosa possiamo fare noi fuori dagli USA? Come posso impostare il valore della specifica ma visualizzare un formato data personalizzato? cioè nel Regno Unito?
Piotr Kula,

3
@ MarjanVenema- Ho usato "ExtensibleModelMetadataProvider" dal FailTracker di Matt Honeycutt ( github.com/MattHoneycutt/Fail-Tracker ). Guarda sotto la cartella dell'infrastruttura per ModelMetadata. Ho usato quelle classi e poi ho creato un'implementazione del filtro di IModelMetadataFilter. Quando viene chiamato il metodo TransformMetadata, è quindi possibile modificare le proprietà "DisplayFormatString" e "EditFormatString" dei metadati. Spero che questo ti porti nella giusta direzione (a proposito, c'è un ottimo video pluralsight che utilizza Fail-Tracker)
SwampyFox

44

In MVC5.2, aggiungi Date.cshtml alla cartella ~ / 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)
}

Grazie! risolve il "problema" di Chrome menzionato e ovviamente puoi avere un altro formato di visualizzazione sulla tua proprietà datetime!
cmxl

Sì ottima soluzione. Ciò fornisce un eccellente rimedio per quelli di noi che non sono negli Stati Uniti.
Richard McKenna,

Penso che questa sia la migliore soluzione al problema, risolve solo il problema dell'editor e non influisce sulla formattazione del display esistente.
dsghi,

1
L'uso di "Date.cshtml" invece di "DateTime.cshtml" è stata la risposta magica! Funziona anche in MVC 4.
Atron Seige,

Grande! Obrigado.
Guilherme de Jesus Santos,

16

In aggiunta alla risposta di Darin Dimitrov:

Se desideri che questa particolare riga utilizzi un determinato formato (diverso dallo standard), puoi utilizzare in MVC5:

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

Come c'è @all'inizio, è @Value = @Model.Property...ancora necessario @? Intendi solo new { Value = Model.Property...?
user3454439

11

In MVC 3 ho dovuto aggiungere:

using System.ComponentModel.DataAnnotations;

tra gli usi quando si aggiungono proprietà:

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

Soprattutto se stai aggiungendo queste proprietà nel file .edmx come me. Ho scoperto che per impostazione predefinita i file .edmx non hanno questo utilizzo, quindi l'aggiunta di solo proprietà non è sufficiente.


10

Se rimuovi [DataType(DataType.Date)]dal tuo modello, il campo di input in Chrome viene visualizzato come type="datetime"e non mostrerà neanche il datepicker.


Grazie Bernie. Non ho avuto problemi con il selettore visualizzato come lo ero con i dati non inseriti nella casella di input. Questo è buono a sapersi però.
Ben Finkel,

Opera rende però un datepicker. Usa modernizr per fare un po 'di polyfill
cleftheris,

1
Se si suppone che sia una data, deve essere visualizzato come input di tipo date. L'uso datetimecome soluzione alternativa è inappropriato, poiché non rappresenta semanticamente i dati.
Chris Pratt,

4

Ho ancora avuto un problema con il passaggio del formato aaaa-MM-gg, ma ho risolto il problema modificando 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"  })
}

grazie finalmente ha funzionato, ho provato string.Format("{0}/{1}/{2}")a ottenere il dd/mm/yyyyformato e funziona benissimo, ho usato il primo metodo del database ma DisplayFormat non ha funzionato con la classe parziale, non so perché ?, comunque qualcuno se necessario prova questo metodo, non l'ho fatto non provare, ma se qualcuno ha bisogno, spero che sia d'aiuto
shaijut

3

Rispondi a MVC4 DataType.Date Editor Per non visualizzare il valore della data in Chrome, bene in IE

Nel modello è necessario disporre del seguente tipo di dichiarazione:

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

O

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

Non è necessario utilizzare il seguente attributo:

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

In Date.cshtml usa questo modello:

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

Divertiti! Saluti, Blerton


Se lo fai in questo modo, Chrome non ti darà un selettore di date. Sto usando la tua soluzione, ma sto modificando in modo che 1) FACCIO l' DisplayFormatattributo 2) Cambia il test per verificare se il tipo di browser è chrome, quindi fai @Html.EditorFor(m=>m.EstPurchaseDate)3) Altrimenti fai @Html.TextBox("EstPurchaseDate", dt.ToString("MM/dd/yyyy"))Nota: su # 2, un controllo migliore sarebbe se il browser capisce HTML5, ma non so come farlo.
David,

4
Downvoting per il rilevamento del browser nel codice lato server.
Tetsujin no Oni,

1

Se devi avere il controllo sul formato della data (in altre parole non è accettabile solo il formato aaaa-mm-gg), un'altra soluzione potrebbe essere l'aggiunta di una proprietà helper che è di tipo stringa e aggiungi un validatore di data a quella proprietà e associa questa proprietà all'interfaccia utente.

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

Ed ecco un validatore di date:

[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;
    }
}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.