我正在尝试调用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:从Bar渲染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%>>
此示例的问题是,当通过Index1.aspx解析时,ViewData.ModelMetaData.ContainerType在模板中为空。从我在Brad Wilson's post和其他人那里读到的内容,它与使用IEnumerable及其作为接口有关。
有没有办法确保设置ContainerType?也许是通过创建ModelMetadataProvider?我仔细研究过,但似乎之前确定了ContainerType值,然后传递给Provider。
任何建议都将不胜感激。
答案 0 :(得分:0)
这是我现在已经解决的功能性解决方案,但它有限且有问题,因为它需要将集合转换为模型中的列表,而模板不能识别上下文。
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>
我仍然希望以类似于我之前描述的方式来处理这种情况。因此,模型模板可以自行确定如何格式化输出,而不必创建调用者按名称引用的特殊案例模板。