Как установить свойство DisplayFormatString для объекта ModelMetadata в razor-engine?

У меня есть проект Asp.Net MVC 5. Я пытаюсь использовать DisplayTemplates, чтобы сделать свое представление более динамичным.

Я пытаюсь создать шаблон отображения для любого свойства DateTime. Но по какой-то причине я не могу установить свойство ViewData.ModelMetadata.DisplayFormatString.

Вот как выглядит моя модель просмотра

public class DisplayClientViewModel : IMapFrom
{
    public int Id { get; set; }
    public string Name { get; set; }

    [DisplayFormat(DataFormatString = "{0:MM/dd/yyyy}")]
    public DateTime? EnrolledAt { get; set; }
}

Вот мой DateTime.cshtml вид

@model DateTime?

@if (!Model.HasValue && ViewData.ModelMetadata.NullDisplayText != null)
{
    <span>@ViewData.ModelMetadata.NullDisplayText</span>
}
else if (Model.HasValue)
{
    <span>@Model.Value.ToString(ViewData.ModelMetadata.DisplayFormatString ?? "g")</span>
}

Поскольку мое свойство EnrolledAt украшено [DisplayFormat(DataFormatString = "{0:MM/dd/yyyy}")], я ожидаю, что ViewData.ModelMetadata.DisplayFormatString будет установлено на {0:MM/dd/yyyy} Но по какой-то причине оно всегда установлено на null.

Как я могу установить свойство ViewData.ModelMetadata.DisplayFormatString в ModelMetadata из модели представления или получить доступ к значению DisplayFormat.DataFormatString?

Примечание. Я знаю, что могу украсить свойство [DataType(DataType.Data)] и создать шаблон Date.cshtml, который будет отображать только короткую дату. Но в этом случае я надеюсь, что смогу работать с любым форматом, а не только с датой или временем.


person Junior    schedule 08.08.2018    source источник
comment
Предполагая, что ваш DateTime.cshtml находится в папке /Views/Shared/DisplayTemplates, и вы используете @Html.DisplayFor(m => m.EnrolledAt) в главном представлении, тогда ViewData.ModelMetadata.DisplayFormatString не будет null (поэтому есть какой-то другой код, который вы не показали, вызывающий проблему.   -  person    schedule 09.08.2018
comment
Но в любом случае при использовании @Model.Value.ToString(ViewData.ModelMetadata.DisplayFormatString ?? "g") будет отображаться {0:08/09/2018} на основе сегодняшней даты. Это должно быть <span>@string.Format(ViewData.ModelMetadata.DisplayFormatString ?? "{0:g}", Model.Value)</span>   -  person    schedule 09.08.2018
comment
@StephenMuecke, что это может быть. Я показываю код, как я его использую. Кроме того, когда я использую его в форме EditorFor и с [Required, DisplayFormat(DataFormatString = "{0:MM/dd/yyyy}", ApplyFormatInEditMode = true)], он все еще показывает время в текстовом поле. Что касается форматирования, как это будет использовать формат g, если формат не задан?   -  person Junior    schedule 09.08.2018
comment
Поскольку DisplayFormatString равно null, используется строка формата "{0:g}". Но я предполагаю, что это связано с вашими предыдущими вопросами, где вы используете object?   -  person    schedule 09.08.2018
comment
Да, это связано с предыдущим вопросом, я использую Html.DisplayFor(x => columnMetadata.Model, columnMetadata.DataTypeName) для отображения значения и использую EditorFor(x => x.PropertyName) для отображения текстового поля. stackoverflow.com/questions/51718933/   -  person Junior    schedule 09.08.2018
comment
Как я и подозревал :) - columnMetadata.Model передает только значение свойства. У него нет метаданных. (и в качестве примечания, EditorFor() предназначен для EditorTemplates, т.е. для редактирования данных и будет содержать элементы управления формы - вы просто отображаете данные, поэтому используйте DisplayTemplate и DisplayFor()   -  person    schedule 09.08.2018
comment
Конечно, вы можете передать DataFormatString шаблону, используя перегрузку, которая принимает additionalViewData, но, как я уже отмечал в предыдущем вопросе, для этого вам нужно создать собственный метод расширения HtmlHelper. (вас ждет мир боли, если вы продолжите идти по этому пути)   -  person    schedule 09.08.2018
comment
Но есть много других метаданных, которые было бы полезно передать, например NullDisplayText или HtmlEncode. Мне нужно передавать их вручную? я не могу просто передать все вместе? Я думаю, что у меня такая же проблема с редактором... так как я также не передаю 3-й аргумент   -  person Junior    schedule 09.08.2018
comment
Давайте продолжим это обсуждение в чате.   -  person    schedule 09.08.2018