program tip

asp.net mvc 4에서 datetime 형식 지정

radiobox 2020. 12. 30. 08:02
반응형

asp.net mvc 4에서 datetime 형식 지정


asp.net mvc 4에서 datetime 형식을 어떻게 강제 할 수 있습니까? 디스플레이 모드에서는 내가 원하는대로 표시되지만 편집 모델에서는 표시되지 않습니다. displayfor 및 editorfor 및 applyformatineditmode = true를 dataformatstring = "{0 : dd / MM / yyyy}"와 함께 사용하고 있습니다.

  • 내 문화와 uiculture로 web.config (둘 다)의 세계화.
  • application_start ()에서 문화와 uiculture 수정
  • datetime에 대한 사용자 정의 modelbinder

강제하는 방법을 모르고 날짜를 기본값이 아닌 dd / MM / yyyy로 입력해야합니다.

추가 정보 : 내 viewmodel은 다음과 같습니다.

    [DisplayName("date of birth")]
    [DataType(DataType.Date)]
    [DisplayFormat(DataFormatString = "{0:dd/MM/yyyy}", ApplyFormatInEditMode = true)]
    public DateTime? Birth { get; set; }

보기에서 사용 @Html.DisplayFor(m=>m.Birth)하지만 예상대로 작동하고 (형식이 표시됩니다) 사용하는 날짜를 입력 @Html.EditorFor(m=>m.Birth)하지만 2000 년 12 월 13 일과 같은 것을 입력하면 유효한 날짜가 아니라는 오류와 함께 실패합니다 (12 / 13/2000 및 2000/12/13이 예상대로 작동하지만 dd / MM / yyyy가 필요합니다).

사용자 정의 modelbinder는 application_start ()에서 호출됩니다. b / c 다른 곳을 모릅니다.

사용 <globalization/>전으로 시도 culture="ro-RO", uiCulture="ro"하고 나를 일 / 월 / 년을 줄 것이다 다른 문화. 나는 또한 application_start ()에서 스레드 단위로 설정하려고 시도했습니다 (여기에 많은 예제가 있습니다.


이 질문을 읽을 모든 것에 대해 : Darin Dimitrov의 대답은 클라이언트 유효성 검사가없는 한 작동하는 것 같습니다. 또 다른 접근 방식은 클라이언트 측 유효성 검사를 포함한 사용자 지정 유효성 검사를 사용하는 것입니다. 전체 응용 프로그램을 다시 만들기 전에 이것을 알게되어 기쁩니다.


아, 이제 분명합니다. 값을 다시 묶는 데 문제가있는 것 같습니다. 보기에 표시하지 않습니다. 사실, 이것이 기본 모델 바인더의 결함입니다. [DisplayFormat]모델 속성 을 고려할 사용자 지정 항목을 작성하고 사용할 수 있습니다. 여기에 이러한 사용자 지정 모델 바인더를 설명했습니다. https://stackoverflow.com/a/7836093/29407


분명히 몇 가지 문제가 여전히 지속됩니다. 다음은 ASP.NET MVC 3 및 ​​4 RC에서 완벽하게 작동하는 전체 설정입니다.

모델:

public class MyViewModel
{
    [DisplayName("date of birth")]
    [DataType(DataType.Date)]
    [DisplayFormat(DataFormatString = "{0:dd/MM/yyyy}", ApplyFormatInEditMode = true)]
    public DateTime? Birth { get; set; }
}

제어 장치:

public class HomeController : Controller
{
    public ActionResult Index()
    {
        return View(new MyViewModel
        {
            Birth = DateTime.Now
        });
    }

    [HttpPost]
    public ActionResult Index(MyViewModel model)
    {
        return View(model);
    }
}

전망:

@model MyViewModel

@using (Html.BeginForm())
{
    @Html.LabelFor(x => x.Birth)
    @Html.EditorFor(x => x.Birth)
    @Html.ValidationMessageFor(x => x.Birth)
    <button type="submit">OK</button>
}

사용자 정의 모델 바인더 등록 Application_Start:

ModelBinders.Binders.Add(typeof(DateTime?), new MyDateTimeModelBinder());

그리고 커스텀 모델 바인더 자체 :

public class MyDateTimeModelBinder : DefaultModelBinder
{
    public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
    {
        var displayFormat = bindingContext.ModelMetadata.DisplayFormatString;
        var value = bindingContext.ValueProvider.GetValue(bindingContext.ModelName);

        if (!string.IsNullOrEmpty(displayFormat) && value != null)
        {
            DateTime date;
            displayFormat = displayFormat.Replace("{0:", string.Empty).Replace("}", string.Empty);
            // use the format specified in the DisplayFormat attribute to parse the date
            if (DateTime.TryParseExact(value.AttemptedValue, displayFormat, CultureInfo.InvariantCulture, DateTimeStyles.None, out date))
            {
                return date;
            }
            else
            {
                bindingContext.ModelState.AddModelError(
                    bindingContext.ModelName,
                    string.Format("{0} is an invalid date format", value.AttemptedValue)
                );
            }
        }

        return base.BindModel(controllerContext, bindingContext);
    }
}

이제 web.config ( <globalization>요소) 또는 현재 스레드 문화에 설정 한 문화에 관계없이 사용자 지정 모델 바인더는 DisplayFormatnull 허용 날짜를 구문 분석 할 때 특성의 날짜 형식을 사용합니다 .


클라이언트 검증 문제 때문에에서 (심지어 MVC 5) MVC 버그가 발생할 수 있습니다 jquery.validate.unobtrusive.min.js 날짜 / 어떤 방식으로 날짜 형식을 허용하지 않습니다 . 불행히도 수동으로 해결해야합니다.

내 마지막으로 작동하는 솔루션 :

$(function () {
    $.validator.methods.date = function (value, element) {
        return this.optional(element) || moment(value, "DD.MM.YYYY", true).isValid();
    }
});

다음을 포함해야합니다.

@Scripts.Render("~/Scripts/jquery-3.1.1.js")
@Scripts.Render("~/Scripts/jquery.validate.min.js")
@Scripts.Render("~/Scripts/jquery.validate.unobtrusive.min.js")
@Scripts.Render("~/Scripts/moment.js")

다음을 사용하여 moment.js를 설치할 수 있습니다.

Install-Package Moment.js

Darin에게 감사드립니다. create 메서드에 게시 할 수있게되었습니다. BindModel 코드를 다음과 같이 수정 한 후에 만 ​​작동했습니다.

public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
    var displayFormat = bindingContext.ModelMetadata.DisplayFormatString;
    var value = bindingContext.ValueProvider.GetValue(bindingContext.ModelName);

    if (!string.IsNullOrEmpty(displayFormat) && value != null)
    {
        DateTime date;
        displayFormat = displayFormat.Replace("{0:", string.Empty).Replace("}", string.Empty);
        // use the format specified in the DisplayFormat attribute to parse the date
         if (DateTime.TryParse(value.AttemptedValue, CultureInfo.GetCultureInfo("en-GB"), DateTimeStyles.None, out date))
        {
            return date;
        }
        else
        {
            bindingContext.ModelState.AddModelError(
                bindingContext.ModelName,
                string.Format("{0} is an invalid date format", value.AttemptedValue)
            );
        }
    }

    return base.BindModel(controllerContext, bindingContext);
}

이것이 다른 사람을 도울 수 있기를 바랍니다 ...

ReferenceURL : https://stackoverflow.com/questions/11272851/format-datetime-in-asp-net-mvc-4

반응형