使用适当的视图模板绘制项目的标准MVC示例是:
Html.DisplayFor(m => m.Date)
如果Model对象具有名为Date of DateTime的属性,则返回带有Display / DateTime.ascx模板中的HTML的字符串。
假设您想要执行相同的操作,但无法使用强类型版本 - 您在编译时不知道此View的Model类型。你使用旧的:
Html.Display( “日期”);
所以这是困难的部分。
假设模型是IEnumerable。您不知道这些对象在编译时是什么,但在运行时它们恰好是Date类型为Date的对象,如:
public class ModelClass
{
public DateTime Date { get; set; }
}
现在假设您希望View迭代这些对象并渲染每个对象。如果你所关心的只是你可以做到的价值:
<%
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() %>
我显然采取了一些捷径来保持这个例子的重点。
这就是重点 - 我如何实现我为自己写的TODO?我不只是想获得价值 - 我希望它的格式很好,如Html.Display(“Date”)。但是,如果我只是调用Html.Display(“Date”),它会检查Model,这是一个IEnumerable,用于名为Date的属性,它当然没有。 Html.Display不会将对象作为参数用作模型(如Html.Display(obj,“Date”),并且我可以找到的所有类和方法都在内部,所以我可以' t调整并直接调用它们。
必须有一些简单的方法来完成我想要做的事情,但我似乎无法找到它。
只是为了确保我清楚 - 这是DateTime.ascx代码的一个例子:
<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<System.DateTime>" %>
<%= Model.ToString("MM/dd/yyyy") %>
理想情况下,此视图的输出可以采用任何模型,但在本例中是上面3个这些ModelClass对象的列表,将是:
2001年11月10日 2002年11月10日 11/10/2003
因为代码会找到DateTime的Display PartialView并为每个代码适当地渲染它。
那么 - 我如何实现TODO?
答案 0 :(得分:8)
在Phil Haack的这篇优秀文章中查看模板代码。它似乎接近你要找的东西:http://haacked.com/archive/2010/05/05/asp-net-mvc-tabular-display-template.aspx
答案 1 :(得分:0)
我找到了一个可能的解决方案,但我并不喜欢它;它需要使用几个基于文件的模板,这意味着您无法将其轻松地抽象到代码库中以便在多个项目中使用。
观点:
<%
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() %>
查看/共享/ DisplayTableHead.ascx:
<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<Type>" %>
<tr>
<%
foreach (PropertyInfo prop in Model.GetProperties())
{
%>
<th><%= prop.Name %></th>
<%
}
%>
</tr>
查看/共享/ 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中的详细信息 - 比如该特定属性是否设置为显示,是否复杂等等。