web-dev-qa-db-fra.com

MVC4 DataType.Date EditorFor n’affiche pas la date dans Chrome, très bien dans Internet Explorer

J'utilise l'attribut DataType.Date sur mon modèle et un EditorFor à mon avis. Cela fonctionne très bien dans Internet Explorer 8 et Internet Explorer 9 , mais dans Google Chrome , il affiche un sélecteur de date et au lieu d'afficher la valeur il affiche simplement "Mois/Jour/Année" en texte gris estompé.

Pourquoi Google Chrome n'affiche-t-il pas la valeur?

Modèle:

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

Vue:

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

Chrome

Internet Explorer

197
Ben Finkel

Lorsque vous décorez une propriété de modèle avec [DataType(DataType.Date)], le modèle par défaut dans ASP.NET MVC 4 génère un champ de saisie de 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" />

Les navigateurs prenant en charge HTML5 tels que Google Chrome rendent ce champ de saisie avec un sélecteur de date.

Pour afficher correctement la date, la valeur doit être au format 2012-09-28. Citation de la spécification :

valeur: Date complète valide définie dans la [RFC 3339], avec la réserve supplémentaire que la composante de l'année est composée de quatre chiffres ou plus représentant un nombre supérieur. que 0.

Vous pouvez appliquer ce format en utilisant l'attribut DisplayFormat:

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

Dans MVC5.2, ajoutez Date.cshtml au dossier ~/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)
}
41
Charlie

En complément de la réponse de Darin Dimitrov:

Si vous souhaitez uniquement que cette ligne utilise un certain format (différent du format standard), vous pouvez utiliser dans MVC5:

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

Dans MVC 3 je devais ajouter:

using System.ComponentModel.DataAnnotations;

parmi les utilisations lors de l'ajout de propriétés:

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

Surtout si vous ajoutez ces propriétés dans un fichier .edmx comme moi. J'ai trouvé que par défaut, les fichiers .edmx n'ont pas cette utilisation, aussi l'ajout de propriétés ne suffit pas.

11
Azoro

Si vous supprimez [DataType(DataType.Date)] de votre modèle, le champ de saisie situé dans Chrome est affiché sous la forme type="datetime" et n'affiche pas non plus le sélecteur de date.

10
bernieb

J'ai toujours eu un problème avec le passage du format aaaa-MM-jj, mais je l'ai contourné en changeant le 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"  })
}
4
markpcasey

Répondre à MVC4 DataType.Date EditorFor n’affiche pas la date dans Chrome, très bien dans IE

Dans le modèle, vous devez avoir le type de déclaration suivant:

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

OR

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

Vous n'avez pas besoin d'utiliser l'attribut suivant:

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

Au Date.cshtml, utilisez ce template:

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

S'amuser! Cordialement, Blerton

3
Blerton Hoxha

Si vous avez besoin de contrôler le format de la date (en d'autres termes, le format aaaa-mm-jj n'est pas acceptable), une autre solution pourrait être d'ajouter une propriété auxiliaire de type chaîne et d'ajouter un validateur de date à cette propriété. et se lient à cette propriété sur l'interface utilisateur.

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

Et voici un validateur de 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;
    }
}
1
Martin Staufcik