MVC4 DataType.Date EditorForは、Chromeでは日付値を表示しません。InternetExplorerでは正常です。


198

モデルのDataType.Date属性とビューのEditorForを使用しています。これはInternet Explorer 8Internet 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>

クロム

インターネットエクスプローラ

回答:


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

Google ChromeなどのHTML5をサポートするブラウザーは、この入力フィールドを日付ピッカーでレンダリングします。

日付を正しく表示するには、値の形式をにする必要があります2012-09-28仕様からの引用:

値: [RFC 3339]で定義されている有効な完全な日付。年の構成要素は、0より大きい数値を表す4桁以上であるという追加の条件付き。

次のDisplayFormat属性を使用してこの形式を適用できます。

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

44
ダリンさん、ありがとうございました!過去2年間に私のMVCの質問の多くに答えてきました。
ベンフィンケル2012

3
すばらしい答えですが、コントロールが適切に機能するように強制する必要があるのは魅力的だと思います。
警官隊2013年

7
マークされたすべてのプロパティに対してこれを「グローバルに」行う方法は[DataType(DataType.Date)]何ですか?これらのプロパティを個別にマークする必要がないので、いくつかのプロパティが欠落するリスクがありますか?
Marjan Venema 2013

7
ダリン、アメリカ国外の人たちは何ができるの?仕様値を設定してカスタム日付形式を表示するにはどうすればよいですか?つまり、英国?
Piotr Kula 14

3
@ MarjanVenema- Matt HoneycuttのFailTracker(github.com/MattHoneycutt/Fail-Tracker)の「ExtensibleModelMetadataProvider」を使用しました。インフラストラクチャフォルダーの下でModelMetadataを確認します。これらのクラスを使用して、IModelMetadataFilterのフィルター実装を作成しました。TransformMetadataメソッドが呼び出されると、メタデータの「DisplayFormatString」および「EditFormatString」プロパティを編集できます。これがあなたを正しい方向に導いてくれることを願っています(ところで、Fail-Trackerを使用する素晴らしい複数形ビデオがあります)
SwampyFox 14

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

ありがとう!言及されたクロームの「問題」を修正し、もちろんあなたはあなたのdatetimeプロパティに別のdisplayformatを持つことができます!
cmxl 2015年

はい、素晴らしいソリューションです。これは、米国にいない私たちにとって素晴らしい回避策を提供します。
Richard McKenna 2015

これは問題の最良の解決策だと思います。これはエディターの問題のみを修正し、既存の表示フォーマットには影響しません。
dsghi 2015

1
「DateTime.cshtml」の代わりに「Date.cshtml」を使用することが魔法の答えでした!MVC 4でも動作します。
Atron Seige

すごい!オブリガード。
ギルヘルムデジーザスサントス

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 2018年

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"、日付ピッカーも表示されません。


バーニーに感謝します。入力ボックスにデータが入力されないのと同じように、ピッカーが表示されるのでそれほど問題ではありませんでした。これは知っておくと良いです。
Ben Finkel、2012年

Operaは日付ピッカーをレンダリングします。modernizrを使用してポリフィルを実行します
cleftheris

1
日付であることが想定されている場合は、typeの入力としてレンダリングする必要がありますdatedatetimeデータを意味的に表さないため、回避策としての使用は不適切です。
クリスプラット

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 EditorForに返信すると、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
サーバー側コードでのブラウザー検出に対する反対投票。
鉄人の鬼

1

日付の形式を制御する必要がある場合(つまり、yyyy-mm-dd形式だけでなく、許容できる場合)、別の解決策は、文字列型のヘルパープロパティを追加し、そのプロパティに日付バリデーターを追加することです。 、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");
        }
    }

そしてここに日付バリデータがあります:

[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;
    }
}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.