Как отформатировать значение в строгом типизированном представлении при использовании Html.TextBoxFor для ASP.Net MVC - PullRequest
17 голосов
/ 18 января 2010

Я пытаюсь отформатировать дату, отображаемую TextBox для ASP.Net MVC, используя значение строго типизированного представления.Дата может быть нулевой, поэтому, если она пустая, я хочу увидеть пустое значение, в противном случае я хочу видеть ее в формате ММ / дд / гггг.

<%= Html.TextBoxFor(model => model.BirthDate, new { style = "width: 75px;" })%>

Спасибо,
Пол Сперанса

Ответы [ 11 ]

25 голосов
/ 15 января 2011

Вы можете сохранить строгую типизацию, используя пользовательский шаблон редактора и Html.EditorFor() вместо Html.TextBoxFor().

Создайте новую папку EditorTemplates в папке / Views / Shared и добавьте новую MVC 2 View User Control с именем 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.

10 голосов
/ 25 января 2013

MVC4 http://msdn.microsoft.com/en-us/library/hh833694.aspx

@Html.TextBoxFor(model => model.YOUR_DATE, "{0:MM/dd/yyyy}")
4 голосов
/ 11 февраля 2010

Сначала добавьте это расширение для получения пути к свойству:

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" }) %>
2 голосов
/ 18 февраля 2012

Можно рассмотреть следующий пример метода TextBoxFor Extension для данных даты и времени:

    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 });
       }
2 голосов
/ 23 февраля 2010

Это грязный хак, но, похоже, работает.

<%= Html.TextBoxFor(model => model.SomeDate,
    new Dictionary<string, object> { { "Value", Model.SomeDate.ToShortDateString() } })%>

Вы получаете привязку модели и можете переопределить свойство HTML «значение» текстового поля с помощью отформатированной строки.

1 голос
/ 16 февраля 2012

Просто назовите его, что он ищет. Как:

Html.TextBox("Person.StartTime",Person.StartTime.ToShortDateString());

Когда он вернется к контроллеру, ваша модель будет иметь ограниченное значение.

0 голосов
/ 20 января 2011

Серьезно, почему представление должно делать это?

Сопоставьте вашу базовую модель, которая имеет объект даты и времени, с вашей моделью представления 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 в действии (Мэннинг)

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; }
}

Эта модель намеренно проста; он состоит в основном из строк. Это то, что мы представляем, в конце концов: текст на странице. Логика, которая отображает данные в этом объекте, будет прямой; представление только выведет это. Модель презентации предназначена для минимизировать принятие решений в представлении.

0 голосов
/ 18 января 2011

Я использую некоторые пользовательские помощники и успешно использовал их в MVC 2 и 3 (код также на Snipplr ). У помощников есть некоторая логика css, когда я использую средство выбора даты jQuery-ui, но это легко можно удалить.

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);
    }
0 голосов
/ 29 апреля 2010

Простое решение состоит в том, чтобы не использовать строго типизированный помощник.

<%= Html.TextBox("StartDate", string.Format("{0:d}", Model.StartDate)) %>
0 голосов
/ 19 января 2010

Вы пытались заставить культуру вашего текущего приложения потока? Вы можете переопределить его в файле 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"/>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...