Формат даты на привязке (ASP.NET MVC)
В моем приложении ASP.net MVC у меня есть представление, которое выглядит так:
...
<label>Due Date</label>
<%=Html.TextBox("due")%>
...
Я использую ModelBinder
для привязки сообщения к моей модели (свойство due имеет тип DateTime
). Проблема заключается в том, что я помещаю "01/01/2009" в текстовое поле, и сообщение не проверяется (из-за неправильного ввода других данных). Связывание переписывает его с датой и временем "01/01/2009 00:00:00".
Есть ли способ сообщить связующему правилу правильно отформатировать дату (т.е. ToShortDateString()
)?
Ответы
Ответ 1
Я просто наткнулся на это очень простое и элегантное решение, доступное в MVC 2:
http://geekswithblogs.net/michelotti/archive/2010/02/05/mvc-2-editor-template-with-datetime.aspx
В основном, если вы используете MVC 2.0, используйте в своем представлении следующее.
<%=Html.LabelFor(m => m.due) %>
<%=Html.EditorFor(m => m.due)%>
затем создайте частичный вид в /Views/Shared/EditorTemplates, названный DateTime.ascx
<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<System.DateTime?>" %>
<%=Html.TextBox("", (Model.HasValue ? Model.Value.ToShortDateString() : string.Empty), new { @class = "datePicker" }) %>
При вызове EditorFor < > он найдет соответствующий шаблон редактора.
Ответ 2
Украсьте свойство в своей модели атрибутом DataType
и укажите, что его a Date
, а не a DateTime
:
public class Model {
[DataType(DataType.Date)]
public DateTime? Due { get; set; }
}
Вам нужно использовать EditorFor
вместо TextBoxFor
в представлении:
@Html.EditorFor(m => m.Due)
Ответ 3
Это грязный хак, но, похоже, он работает.
<%= Html.TextBoxFor(model => model.SomeDate,
new Dictionary<string, object> { { "Value", Model.SomeDate.ToShortDateString() } })%>
Вы получаете привязку к модели и можете переопределить свойство "значение" HTML в текстовом поле с форматированной строкой.
Ответ 4
Почему бы вам не использовать
<% =Html.TextBox("due", Model.due.ToShortDateString()) %>
Ответ 5
Я нашел этот вопрос, ища сам ответ. Вышеупомянутые решения не работали для меня, потому что мой DateTime имеет значение NULL. Здесь, как я решил это с поддержкой для объектов с нулевым значением DateTime.
<%= Html.TextBox(String.Format("{0:d}", Model.Property)) %>
Ответ 6
Сначала добавьте это расширение для получения пути свойства:
public static class ExpressionParseHelper
{
public static string GetPropertyPath<TEntity, TProperty>(Expression<Func<TEntity, TProperty>> property)
{
Match match = Regex.Match(property.ToString(), @"^[^\.]+\.([^\(\)]+)$");
return match.Groups[1].Value;
}
}
Затем добавьте это расширение для HtmlHelper:
public static MvcHtmlString DateBoxFor<TEntity>(
this HtmlHelper helper,
TEntity model,
Expression<Func<TEntity, DateTime?>> property,
object htmlAttributes)
{
DateTime? date = property.Compile().Invoke(model);
var value = date.HasValue ? date.Value.ToShortDateString() : string.Empty;
var name = ExpressionParseHelper.GetPropertyPath(property);
return helper.TextBox(name, value, htmlAttributes);
}
Также вы должны добавить этот код jQuery:
$(function() {
$("input.datebox").datepicker();
});
datepicker - это плагин jQuery.
И теперь вы можете использовать его:
<%= Html.DateBoxFor(Model, (x => x.Entity.SomeDate), new { @class = "datebox" }) %>
ASP.NET MVC2 и формат DateTime
Ответ 7
Чтобы получить строго типизированный доступ к вашей модели в коде позади вашего представления, вы можете сделать это:
public partial class SomethingView : ViewPage<T>
{
}
Где T - тип ViewData, который вы хотите передать из своего действия.
Затем в вашем контроллере вы будете иметь действие:
public ActionResult Something(){
T myObject = new T();
T.Property = DateTime.Today();
Return View("Something", myObject);
}
После этого у вас есть хорошие сильно типизированные данные модели в вашем представлении, чтобы вы могли:
<label>My Property</label>
<%=Html.TextBox(ViewData.Model.Property.ToShortDateString())%>
Ответ 8
Я считаю, что лучший способ сделать это - reset ModelValue
ModelState.SetModelValue("due", new ValueProviderResult(
due.ToShortDateString(),
due.ToShortDateString(),
null));
Ответ 9
Я предполагаю, что лично я бы сказал, что это лучше всего или проще всего сделать с помощью строго типизированной страницы и определенного класса модели, но если вы хотите, чтобы это было чем-то, что живет в связующем, я бы сделал это следующим образом:
public class SomeTypeBinder : IModelBinder
{
public object GetValue(ControllerContext controllerContext, string modelName,
Type modelType, ModelStateDictionary modelState)
{
SomeType temp = new SomeType();
//assign values normally
//If an error then add formatted date to ViewState
controllerContext.Controller.ViewData.Add("FormattedDate",
temp.Date.ToShortDateString());
}
}
И затем используйте это в представлении при создании текстового поля i.e.:
<%= Html.TextBox("FormattedDate") %>
Надеюсь, что это поможет.
Ответ 10
Это сработало для меня: mvc 2
<%: Html.TextBoxFor(m => m.myDate, new { @value = Model.myDate.ToShortDateString()}) %>
Простые и сладкие!
Комментарий пользователя82646, думал, что сделаю его более заметным.
Ответ 11
Попробуйте это
<%:Html.TextBoxFor(m => m.FromDate, new { @Value = (String.Format("{0:dd/MM/yyyy}", Model.FromDate)) }) %>
Ответ 12
MVC4 EF5 View Я пытался предварительно загрузить поле с сегодняшней датой и передать его на утверждение для утверждения.
ViewModel.SEnd = DateTime.Now //preload todays date
return View(ViewModel) //pass to view
В представлении мой первый код разрешил редактирование:
@Html.EditedFor(item.SEnd) //allow edit
Позже я изменил его, чтобы просто отобразить дату, пользователь не может ее изменить, но отправитель запускает сохранение контроллера
<td>
@Html.DisplyFor(item.SEnd) //show no edit
</td>
Когда я перешел на DisplayFor, мне нужно было добавить это, чтобы гарантировать, что предварительно загруженное значение было передано обратно контроллеру. Мне также нужно добавить HiddenFor для каждого поля в модели просмотра.
@Html.HiddenFor(model => model.SEnd) //preserve value for passback.
Новички, но это заняло некоторое время, чтобы решить эту проблему.