Как форматировать значение в сильном типизированном представлении при использовании ASP.Net MVC Html.TextBoxFor
Я пытаюсь отформатировать дату, предоставленную ASP.Net MVC TextBoxДля использования значения строго типизированного представления. Дата имеет значение null, поэтому, если она равна нулю, я хочу увидеть пустое значение, в противном случае я хочу увидеть его в формате MM/dd/yyyy.
<%= Html.TextBoxFor(model => model.BirthDate, new { style = "width: 75px;" })%>
Спасибо,
Пол Сперанца
Ответы
Ответ 1
Вы можете сохранить сильную типизацию с помощью настраиваемого шаблона редактора и Html.EditorFor()
вместо Html.TextBoxFor()
.
Создайте новую папку EditorTemplates в папке /Views/Shared и добавьте новый элемент управления MVC 2 View с именем DateTime.ascx. Добавьте следующий
<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<System.DateTime?>" %>
<%= Html.TextBox("", (Model.HasValue ? Model.Value.ToString("MM/dd/yyyy") : string.Empty)) %>
Затем в вашем представлении используйте
<%= Html.EditorFor(model => model.BirthDate)%></p>
Не беспокойтесь о "", именование будет по-прежнему работать правильно.
Если вы показываете DateTime в другом формате культуры для культуры приложения по умолчанию, вам необходимо изменить информацию о культуре или создать настраиваемое связующее устройство, чтобы привязка модели работала при отправке DateTime.
Ответ 2
MVC4 http://msdn.microsoft.com/en-us/library/hh833694.aspx
@Html.TextBoxFor(model => model.YOUR_DATE, "{0:MM/dd/yyyy}")
Ответ 3
Сначала добавьте это расширение для получения пути свойства:
public static string GetPropertyPath<TEntity, TProperty>(Expression<Func<TEntity, TProperty>> property)
{
Match match = Regex.Match(property.ToString(), @"^[^\.]+\.([^\(\)]+)$");
return match.Groups[1].Value;
}
Затем добавьте расширения для HtmlHalper:
public static MvcHtmlString DateBoxFor<TEntity>(
this HtmlHelper helper,
TEntity model,
Expression<Func<TEntity, DateTime?>> property,
object htmlAttributes)
{
DateTime? date = property.Compile().Invoke(model);
// Here you can format value as you wish
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" }) %>
Ответ 4
Это грязный хак, но, похоже, он работает.
<%= Html.TextBoxFor(model => model.SomeDate,
new Dictionary<string, object> { { "Value", Model.SomeDate.ToShortDateString() } })%>
Вы получаете привязку к модели и можете переопределить свойство "значение" HTML в текстовом поле с форматированной строкой.
Ответ 5
Вы можете рассмотреть следующий образец метода TextBoxFor Extension для данных datetime:
public static MvcHtmlString CalenderTextBoxFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression)
{
Func<TModel, TProperty> deleg = expression.Compile();
var result = deleg(htmlHelper.ViewData.Model);
string value = null;
if (result.ToString() == DateTime.MinValue.ToString())
value = string.Empty;
else
value = string.Format("{0:M-dd-yyyy}", result);
return htmlHelper.TextBoxFor(expression, new { @class = "datepicker text", Value = value });
}
Ответ 6
Просто назовите его, что он ищет. Как:
Html.TextBox("Person.StartTime",Person.StartTime.ToShortDateString());
Когда он вернется к контроллеру, ваша модель будет иметь ограниченное значение.
Ответ 7
Вы пытались заставить культуру использовать текущее приложение? Вы можете переопределить его в файле web.config с помощью этой строки (в теге):
<!-- Default resource files are set here. The culture will also change date format, decimal, etc... -->
<globalization enableClientBasedCulture="false" culture="en-US" uiCulture="en-US"/>
Ответ 8
Простое решение - не использовать строго типизированный помощник.
<%= Html.TextBox("StartDate", string.Format("{0:d}", Model.StartDate)) %>
Ответ 9
Я использую некоторые пользовательские помощники и успешно использовал их в MVC 2 и 3 (код также на Snipplr). У помощников есть какая-то css-логика, в которую я использую jQuery-ui datepicker, но это можно легко удалить.
public static MvcHtmlString DateTextBoxFor<TModel, TValue>(this HtmlHelper<TModel> helper, Expression<Func<TModel, TValue>> expression, string formatString, object htmlAttributes)
{
var metadata = ModelMetadata.FromLambdaExpression(expression, helper.ViewData);
string format = String.IsNullOrEmpty(formatString) ? "M/d/yyyy" : formatString;
DateTime date = metadata.Model == null ? new DateTime() : DateTime.Parse(metadata.Model.ToString());
string value = date == new DateTime() ? String.Empty : date.ToString(format);
RouteValueDictionary attributes = new RouteValueDictionary(htmlAttributes);
string datePickerClass = "date-selector";
if (attributes.ContainsKey("class"))
{
string cssClass = attributes["class"].ToString();
attributes["class"] = cssClass.Insert(cssClass.Length, " " + datePickerClass);
}
else
{
attributes["class"] = datePickerClass;
}
return helper.TextBox(ExpressionHelper.GetExpressionText(expression), value, attributes);
}
public static MvcHtmlString DateTextBoxFor<TModel, TValue>(this HtmlHelper<TModel> helper, Expression<Func<TModel, TValue>> expression)
{
return DateTextBoxFor<TModel, TValue>(helper, expression, String.Empty, null);
}
public static MvcHtmlString DateTextBoxFor<TModel, TValue>(this HtmlHelper<TModel> helper, Expression<Func<TModel, TValue>> expression, string formatString)
{
return DateTextBoxFor<TModel, TValue>(helper, expression, formatString, null);
}
Ответ 10
Серьезно, почему это должно выглядеть?
Сопоставьте свою основную модель, у которой есть объект времени даты, к вашей модели представления mvc.
//core model
public class Person
{
public DateTime? BirthDate { get; set;}
}
//view model
public class PersonForm
{
public string BirthDate { get; set; }
}
Таким образом, отображение может выглядеть так:
public interface IDomainToViewMapper<TModel, TViewModel>
{
/// <summary>
/// Use an automapper or custom implementation to map domain model to presentation model.
/// </summary>
/// <param name="source">domain model</param>
/// <returns>presentation model</returns>
TViewModel MapDomainToView(TModel source);
}
public interface IPersonMapper : IDomainToViewMapper<Person, PersonForm>
{
}
public class PersonMapper : IPersonMapper
{
#region IDomainToViewMapper<Person,PersonForm> Members
public PersonForm MapDomainToView(Person source)
{
PersonForm p = new PersonForm();
if (source.BirthDate.HasValue)
{
p.BirthDate = source.BirthDate.Value.ToShortDateString();
}
return p;
}
#endregion
}
И ваше действие контроллера может выглядеть так:
public ActionResult Index()
{
Person person = //get person;
var personForm = _personMapper.MapDomainToView(person);
return View(personForm)
}
Вам больше не придется менять свой пример.
Из главы 2, MVC 2 в действии (Manning)
public class CustomerSummary
{
public string Name { get; set; }
public bool Active { get; set; }
public string ServiceLevel { get; set; }
public string OrderCount { get; set;}
public string MostRecentOrderDate { get; set; }
}
Эта модель намеренно проста; он состоит в основном из строк. То, что представляли,
в конце концов: текст на странице. Логика, отображающая данные в этом объекте, будет
прямой; представление будет выводить его только. Модель презентации предназначена для
минимизировать принятие решений в представлении.
Ответ 11
Вы пробовали просто передать формат даты, который вам нужен?
Html.TextBoxFor(model => model.BirthDate.ToString("MM/dd/yyyy"),
new { style = "width: 75px;" })