ASP.NET MVC2: можете ли вы получить ModelMetadata.ContainerType из коллекции? - PullRequest
0 голосов
/ 18 июня 2010

Я пытаюсь вызвать DisplayFor и DisplayForModel для итерации IEnumerable <> с различными типами элементов в представлении. У меня есть шаблоны, определенные для каждого элемента / типа модели.

Я хотел бы проверить ViewData.ModelMetadata.ContainerType из шаблона, чтобы шаблон мог определить, был ли он вызван как часть коллекции.

Простой пример:

Index1.aspx: для рендеринга коллекции Foos.

<%@ Page Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<IEnumerable<Foo>>" %>
<asp:Content ContentPlaceHolderID="MainPlaceHolder" runat="server">
    <ul><%:Html.DisplayForModel()%></ul>
</asp:Content>

Index2.aspx: визуализация Foo из бара.

<%@ Page Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<Bar>" %>
<asp:Content ContentPlaceHolderID="MainPlaceHolder" runat="server">
    <%:Html.DisplayFor(m => m.Foo)%>
</asp:Content>

Shared \ DisplayTemplates \ Foo.ascx: контекстно-зависимый шаблон для Foo.

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<Foo>" %>
<%  var tag = typeof(IEnumerable).IsAssignableFrom(ViewData.ModelMetaData.ContainerType) ? "li" : "div";
%>    <<%:tag%>><%:Model.Name%></<%:tag%>>

Проблема с этим примером заключается в том, что ViewData.ModelMetaData.ContainerType в шаблоне имеет значение null, если разрешается через Index1.aspx. Из того, что я прочитал в пост Брэда Уилсона и других, это связано с использованием IEnumerable и его интерфейса.

Есть ли способ убедиться, что установлен тип контейнера? Возможно, создав ModelMetadataProvider? Я кратко рассмотрел это, но кажется, что значение ContainerType определяется до, а затем передается поставщику.

Будем благодарны за любые предложения.

1 Ответ

0 голосов
/ 18 июня 2010

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

Index1.aspx: для отображения коллекции Foos.

<%@ Page Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<IList<Foo>>" %>
<asp:Content ContentPlaceHolderID="MainPlaceHolder" runat="server">
    <%:Html.DisplayForModel("List")%>
</asp:Content>

Shared \ DisplayTemplates \ List.ascx: Специальный шаблон коллекции.

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<IList>" %>
<ul class="list">
<%  for(int i = 0, count = Model.Count; i < count; i++)
    {
%>      <li><%:Html.DisplayFor(m => m[i])%></li>
<%  }
%>
</ul>

Shared \ DisplayTemplates \ Foo.ascx: неконтекстный шаблон для Foo.

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<Foo>" %>
    <div><%:Model.Name%></div>

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

...