Подтвердить что ты не робот

Формат даты и времени в asp.net mvc 4

Как я могу форматировать формат datetime в asp.net mvc 4? В режиме отображения он отображается, как я хочу, но в модели редактирования это не так. Я использую displayfor и editorfor и applyformatineditmode = true с dataformatstring = "{0: dd/MM/yyyy}" Что я пробовал:

  • глобализация в web.config(оба из них) с моей культурой и еструктуризмом.
  • изменение культуры и урологии в application_start()
  • пользовательский шаблон для datetime

Я понятия не имею, как заставить его, и мне нужно ввести дату как dd/MM/yyyy, а не по умолчанию.

ДОПОЛНИТЕЛЬНАЯ ИНФОРМАЦИЯ: моя модель просмотра похожа на это

    [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), но если я попытаюсь ввести что-то вроде 13/12/2000, произойдет ошибка с ошибкой, что это не действительная дата (12/13/2000 и 2000/12/13 работают как но мне нужно dd/MM/yyyy).

Пользовательский modelbinder вызывается в application_start() b/c. Я не знаю, где еще.

Используя <globalization/>, я попытался использовать culture="ro-RO", uiCulture="ro" и другие культуры, которые дадут мне dd/MM/yyyy. Я также попытался установить его на основе потока в application_start() (здесь есть много примеров, как это сделать)


Для всего, что прочитает этот вопрос: Кажется, что Дарин Димитров ответ будет работать, пока у меня нет проверки клиента. Другим подходом является использование специальной проверки, включая проверку на стороне клиента. Я рад, что нашел это, прежде чем воссоздать все приложение.

4b9b3361

Ответ 1

Ahhhh, теперь ясно. Кажется, у вас проблемы с привязкой значения. Не показывать его на экране. В самом деле, это ошибка типового связующего. Вы можете написать и использовать пользовательский, который будет учитывать атрибут [DisplayFormat] на вашей модели. Я проиллюстрировал здесь такое настраиваемое связующее устройство: fooobar.com/questions/102628/...


По-видимому, некоторые проблемы все еще сохраняются. Здесь моя полная настройка работает отлично на обоих 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>) или текущую культуру потока, пользовательское связующее устройство будет использовать формат даты атрибута DisplayFormat при анализе дат нулевых значений.

Ответ 2

Спасибо Дарин, Для меня, чтобы отправлять сообщение в метод 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);
}

Надеюсь, это поможет кому-то еще...

Ответ 3

Проблемы с проверкой клиента могут возникать из-за ошибки MVC (даже в MVC 5) в 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