Почему мой DisplayFor не зацикливается на моем IEnumerable <DateTime>?
У меня есть эта строка в моем представлении
@(Html.DisplayFor(m => m.DaysOfWeek, "_CourseTableDayOfWeek"))
где m.DaysOfWeek
- IEnumerable<DateTime>
.
Содержимое _CourseTableDayOfWeek.cshtml:
@model DateTime
@{
ViewBag.Title = "CourseTableDayOfWeek";
}
<th>
@System.Globalization.CultureInfo.CurrentCulture.DateTimeFormat.DayNames[(int) Model.DayOfWeek]
<span class="dateString">Model.ToString("G")</span>
</th>
И я получаю следующую ошибку:
Элемент модели, переданный в словарь, имеет тип "System.Collections.Generic.List`1[System.DateTime]
", но для этого словаря требуется элемент модели типа "System.DateTime
".
Если я ссылаюсь на следующее сообщение:
qaru.site/info/125100/...
DisplayFor
должен зацикливаться на IEnumerable и отображать шаблон для каждого элемента, не так ли?
Ответы
Ответ 1
Он не зацикливается, потому что вы указали имя для шаблона отображения в качестве второго аргумента хелпера DisplayFor
(_CourseTableDayOfWeek
).
Он зацикливается только тогда, когда вы полагаетесь на соглашения, т.е.
@Html.DisplayFor(m => m.DaysOfWeek)
а затем внутри ~/Views/Shared/DisplayTemplates/DateTime.cshtml
:
@model DateTime
@{
ViewBag.Title = "CourseTableDayOfWeek";
}
<th>
@System.Globalization.CultureInfo.CurrentCulture.DateTimeFormat.DayNames[(int) Model.DayOfWeek]
<span class="dateString">Model.ToString("G")</span>
</th>
После того, как вы укажете собственное имя для шаблона отображения (либо в качестве второго аргумента для вспомогательного элемента DisplayFor, либо как атрибут [UIHint]
), он больше не будет зацикливаться на свойствах коллекции, и шаблон будет просто передан как IEnumerable<T>
как модель,
Это сбивает с толку, но так оно и есть. Мне тоже это не нравится.
Ответ 2
Это похоже на ошибку. Классы Html Helper легко расширяются, хотя, посмотрев на источник MVC, ища ошибку, я отказался и просто использовал предположение, что шаблоны работают для отдельного элемента, поэтому я написал расширение HtmlHelper, которое завершает его для вас. Я вытащил лямбда-выражение для своей простоты, но вы можете легко вернуться к этому. Этот пример предназначен только для списка строк.
public static class DisplayTextListExtension
{
public static MvcHtmlString DisplayForList<TModel>(this HtmlHelper<TModel> html, IEnumerable<string> model, string templateName)
{
var tempResult = new StringBuilder();
foreach (var item in model)
{
tempResult.Append(html.DisplayFor(m => item, templateName));
}
return MvcHtmlString.Create(tempResult.ToString());
}
}
Тогда фактическое использование выглядит следующим образом:
@Html.DisplayForList(Model.Organizations, "infoBtn")
Ответ 3
Небольшой твик, позволяющий этому решению Dan быть немного более общим:
public static class DisplayTextListExtension
{
public static MvcHtmlString DisplayForList<TModel,
EModel>(this HtmlHelper<TModel> html, IEnumerable<EModel> model, string templateName)
{
var tempResult = new StringBuilder();
foreach (var item in model)
{
tempResult.Append(html.DisplayFor(m => item, templateName));
}
return MvcHtmlString.Create(tempResult.ToString());
}
}
Ответ 4
Используйте FilterUIHint
вместо обычного UIHint
в свойстве IEnumerable<T>
.
public class MyModel
{
[FilterUIHint("_CourseTableDayOfWeek")]
public IEnumerable<DateTime> DaysOfWeek { get; set; }
}
Не нужно ничего другого.
@Html.DisplayFor(m => m.DaysOfWeek)
Теперь отображается "_CourseTableDayOfWeek"
EditorTemplate для каждого DateTime
в DaysOfWeek
.