Internet Explorer에서 MVC4 DataType.Date EditorFor가 Chrome에 날짜 값을 표시하지 않음


198

내 모델에서 DataType.Date 특성을 사용하고 있으며 뷰에서 EditorFor를 사용하고 있습니다. 이것은 Internet Explorer 8Internet Explorer 9 에서 잘 작동 하지만 Chrome 에서는 날짜 선택기를 표시하고 값을 표시하는 대신 희미한 회색 텍스트로 "월 / 일 / 년"만 표시합니다.

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

Chrome과 같은 HTML5를 지원하는 브라우저는 날짜 선택기로이 입력 필드를 렌더링합니다.

날짜를 올바르게 표시하려면 값을 형식으로 지정해야합니다 2012-09-28. 사양 에서 인용 :

value : [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 질문에 답하셨습니다.
Ben Finkel

3
대단한 답변이지만 이것이 컨트롤이 제대로 작동하도록 강요해야한다는 것이 매력적이라고 ​​생각합니다!
Coops

7
표시된 모든 속성에 대해 "전역 적으로"이 작업을 수행하는 방법은 무엇입니까 [DataType(DataType.Date)]? 따라서 일부 속성이 누락 될 위험이있는 속성을 모두 별도로 표시하지 않아도됩니까?
Marjan Venema

7
대린, 미국 이외의 사람들은 무엇을 할 수 있습니까? 사양 값을 설정하고 사용자 정의 날짜 형식을 표시하려면 어떻게해야합니까? 즉, 영국?
Piotr Kula

3
@ MarjanVenema- Matt Honeycutt의 FailTracker ( github.com/MattHoneycutt/Fail-Tracker ) 의 "ExtensibleModelMetadataProvider"를 사용했습니다 . ModelMetadata의 Infrastructure 폴더 아래를보십시오. 해당 클래스를 사용한 다음 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)
}

감사! 언급 된 크롬 '문제'를 수정하고 물론 datetime 속성에 다른 표시 형식을 가질 수 있습니다!
cmxl

네 훌륭한 솔루션입니다. 이것은 미국이 아닌 사람들에게 훌륭한 해결책을 제공합니다.
Richard McKenna

이것이 문제의 가장 좋은 해결책이라고 생각합니다. 편집기 문제 만 수정하고 기존 디스플레이 형식에는 영향을 미치지 않습니다.
dsghi

1
"DateTime.cshtml"대신 "Date.cshtml"을 사용하는 것이 정답입니다! MVC 4에서도 작동합니다.
Atron Seige

큰! 오브리가도.
Guilherme de Jesus Santos

16

Darin Dimitrov의 답변 외에도

이 특정 행만 특정 (표준과는 다른) 형식을 사용하도록하려면 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"날짜 선택기가 표시되지 않습니다.


고마워 버니 입력 상자에 데이터를 넣지 않은 상태에서 선택기가 표시되는 데 어려움이 없었습니다. 그래도 알아두면 좋습니다.
Ben Finkel

Opera는 날짜 선택기를 렌더링합니다. 현대화를 사용하여 일부 폴리 필 수행
cleftheris

1
날짜 여야한다면 유형의 입력으로 렌더링해야합니다 date. datetime의미 적으로 데이터를 나타내지 않으므로 임시 해결책으로 사용 하는 것은 부적절합니다.
Chris Pratt

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 편집기에 회신 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" })
    } 
}

즐기세요! 감사합니다. Blerton


이렇게하면 Chrome에서 날짜 선택기를 제공하지 않습니다. 귀하의 솔루션을 사용하고 있지만 1) DisplayFormat속성을 사용하도록 수정 2) 브라우저 유형이 크롬인지 확인하기 위해 테스트를 변경 한 다음 @Html.EditorFor(m=>m.EstPurchaseDate)3) 그렇지 않습니다. @Html.TextBox("EstPurchaseDate", dt.ToString("MM/dd/yyyy"))참고 : # 2에서 더 나은 확인은 브라우저는 HTML5를 이해하지만 그 방법을 모르겠습니다.
David

4
서버 측 코드에서 브라우저 감지를위한 다운 보팅.
Tetsujin no Oni

1

날짜 형식을 제어해야하는 경우 (즉, yyyy-mm-dd 형식 만 허용되는 것이 아니라) 다른 솔루션은 string 유형의 도우미 속성을 추가하고 해당 속성에 날짜 유효성 검사기를 추가하는 것일 수 있습니다. 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.