ASP.Net MVC: Html.Display () для объекта в коллекции - PullRequest
4 голосов
/ 20 октября 2010

Стандартный пример MVC для рисования элемента с соответствующим шаблоном вида:

Html.DisplayFor (m => m.Date)

Если объект Model имеет свойство с именем Dateтипа DateTime, это возвращает строку с HTML из шаблона Display / DateTime.ascx.

Предположим, вы хотели сделать то же самое, но не могли использовать версию со строгим типом - вы не сделализнать тип модели для этого представления во время компиляции.Вы используете более старую версию:

Html.Display ("Date");

Итак, вот сложная часть.

Предположим, что модель IEnumerable.Вы не знаете, что это за объекты во время компиляции, но во время выполнения они снова оказываются объектами с датой типа DateTime, например:

public class ModelClass
{
    public DateTime Date { get; set; }
}

Теперь предположим, что вы хотите, чтобы ваш просмотр былпереберите эти объекты и визуализируйте каждый из них.Если бы все, что вас беспокоило, это ценность, которую вы могли бы сделать следующим образом:

<%
StringBuilder sb = new StringBuilder();
foreach(object obj in (IEnumerable<object>)Model)
{
    Type type = obj.GetType();

    foreach(PropertyInfo prop in type.GetProperties())
    {
        // TODO: Draw the appropriate Display PartialView/Template instead
        sb.AppendLine(prop.GetValue(obj, null).ToString());
    }
}
%>
<%= sb.ToString() %>

Я, очевидно, воспользуюсь некоторыми ярлыками, чтобы сфокусировать этот пример.

Вот смысл - как мне выполнить этоТОДО Я написал для себя?Я не просто хочу получить значение - я хочу, чтобы оно было красиво отформатировано как Html.Display («Date»).Но если я просто вызываю Html.Display («Date»), он проверяет Model, которая является IEnumerable, для свойства с именем Date, которое, конечно же, не имеет.Html.Display не принимает объект в качестве аргумента для использования в качестве Модели (например, Html.Display (obj, "Date"), и все классы и методы, которые я могу найти, которые находятся под ними, кажутся внутренними, поэтому я могу 'настроить их напрямую.

Должен быть какой-то простой способ выполнить то, что я пытаюсь сделать, но я не могу найти его.

Просто чтобы убедиться,У меня все понятно - вот пример кода DateTime.ascx:

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<System.DateTime>" %>
<%= Model.ToString("MM/dd/yyyy") %>

И поэтому, в идеале, вывод из этого представления может принимать любую модель, но в данном случае это список из 3из этих объектов ModelClass, приведенных выше, будет:

11/10/10 2001 11/10/2002 11/10/2003

Поскольку код найдет Display PartialView для DateTime и отобразит его соответствующим образомдля каждого.

Итак - как мне выполнить ТОДО?

Ответы [ 2 ]

8 голосов
/ 20 октября 2010

Посмотрите код шаблона в этом прекрасном посте от Фила Хаака. Кажется, что это близко к тому, что вы ищете: http://haacked.com/archive/2010/05/05/asp-net-mvc-tabular-display-template.aspx

0 голосов
/ 21 октября 2010

Я нашел одно потенциальное решение для этого, но я не влюблен в него; это требует использования нескольких файловых шаблонов, а это означает, что вы не можете легко преобразовать это в библиотеку кода для использования в нескольких проектах.

Вид:

<%
StringBuilder sb = new StringBuilder();

Type itemType = Model.GetType().GetGenericArguments()[0];

sb.AppendLine("<table>");

// Pass in the Model (IEnumerable<object>)'s generic item type as
// the Model for a PartialView that draws the header
sb.Append(Html.Partial("DisplayTableHead", itemType));

foreach(object item in (IEnumerable<object>)Model)
{
    sb.Append(Html.Partial("DisplayTableRow", item));
}

sb.AppendLine("</table>");
%>
<%= sb.ToString() %>

Views / Shared / DisplayTableHead.ascx:

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<Type>" %>
<tr>
<%
foreach (PropertyInfo prop in Model.GetProperties())
{
%>
<th><%= prop.Name %></th>
<%
}
%>
</tr>

Views / Shared / DisplayTableRow.ascx:

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl" %>
<tr>
<%
Type modelType = Model.GetType();

foreach (PropertyInfo modelField in modelType.GetProperties())
{
%>
<td><%= Html.Display(modelField.Name) %></td>
<%
}
%>
</tr>

Но теперь я вижу главный недостаток этого решения, а именно то, что опубликованное решение Clicktricity учитывает детали в ModelMetadata - например, установлено ли это конкретное свойство для отображения, является ли оно сложным или нет, и т.д.

...