Формат даты и времени в 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() (здесь есть много примеров, как это сделать)
Для всего, что прочитает этот вопрос:
Кажется, что Дарин Димитров ответ будет работать, пока у меня нет проверки клиента.
Другим подходом является использование специальной проверки, включая проверку на стороне клиента.
Я рад, что нашел это, прежде чем воссоздать все приложение.
Ответы
Ответ 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