【问题标题】:Avoiding Repetitive View Code in ASP.NET MVC避免在 ASP.NET MVC 中重复查看代码
【发布时间】:2017-11-16 11:29:18
【问题描述】:

这适用于 Razor 视图中的 ASP.NET MVC 4 应用程序。我正在将模型传递给局部视图,并尝试遍历模型中包含的给定属性列表以显示为表格。

鉴于List<string> propertyNames 之类的内容,在此表中,我想以如下结构输出DisplayNameFor 和属性值:

<tr>
    <th>@Html.DisplayNameFor(Model.property)</th>
    <td>@Model.property</td>
</tr>

我必须在部分中执行几次,因为不同的属性对应于部分中的不同 div 元素,其中将插入不同的表,所以我创建了一个助手,这就是我挂断电话的地方.首先,我知道如何做到这一点的唯一方法是反射,我已经读过反射是昂贵的,尤其是一次只做一个属性。另外,使用这种方法,我无法让@Html.DisplayNameFor 正常工作,因为使用反射,我不太了解语法:

@helper IterateDetailPropertyNames(List<string> propertyNames) { 
    foreach (var property in propertyNames)
    {
        <tr>
            <th>
                @Html.DisplayNameFor(m => m.GetType().GetProperty(property).GetValue(Model, null));
                @*Error: Templates can be used only with field access, property access...*@
            </th>
            <td>
                @Model.GetType().GetProperty(property).GetValue(Model, null)
            </td>
        </tr>
    }
}

我怎样才能完成这项工作并改进它?

【问题讨论】:

  • 你试过@Html.DisplayNameFor(m =&gt; m[property]);不涉及反射...
  • 如果您的视图正在使用模型,那么您可以使用ModelMetadata 访问模型的所有属性,包括其显示名称。您是否只想在表格中显示每个属性的显示名称和属性值?
  • @StephenMuecke 是的。这就是它的要点。
  • 然后使用模型ModelMetadata 是要走的路。现在没时间,但我会在 30 分钟左右添加答案。同时,您可能对this project 感兴趣 - 还没有开始编写文档,但在here 中进行了描述

标签: asp.net-mvc-4 razor


【解决方案1】:

模型ModelMetadata 为您提供生成表格所需的数据。除了DisplayNameDisplayFormatStringNullDisplayText 等属性之外,它还包含模型值,这些属性由应用到属性的注释确定。

有关ModelMetadata的更多信息,请参阅documentationASP.NET MVC 2 Templates, Part 2: ModelMetadata

要生成您的表格,您可以编写以下HtmlHelper 扩展方法

public static class TableHelper
{

    public static MvcHtmlString DisplayTableFor<TModel, TProperty>(this HtmlHelper<TModel> helper, Expression<Func<TModel, TProperty>> expression)
    {
        // Get the ModelMetadata for the model
        ModelMetadata metaData = ModelMetadata.FromLambdaExpression(expression, helper.ViewData);
        StringBuilder html = new StringBuilder();
        // Loop through the ModelMetadata of each property in the model
        foreach (ModelMetadata property in metaData.Properties)
        {
            var x = metaData.DisplayFormatString;
            string label = property.DisplayName;
            string value = null;
            if (property.Model == null)
            {
                value = metaData.NullDisplayText;
            }
            else if (metaData.DisplayFormatString != null)
            {
                value = string.Format(metaData.DisplayFormatString, property.Model);
            }
            else
            {
                value = property.Model.ToString();
            }
            TagBuilder labelCell = new TagBuilder("td");
            labelCell.InnerHtml = label;
            TagBuilder valueCell = new TagBuilder("td");
            valueCell.InnerHtml = value;
            StringBuilder innerHtml = new StringBuilder();
            innerHtml.Append(labelCell.ToString());
            innerHtml.Append(valueCell.ToString());
            TagBuilder row = new TagBuilder("tr");
            row.InnerHtml = innerHtml.ToString();
            html.Append(row.ToString());
        }
        TagBuilder table = new TagBuilder("table");
        table.InnerHtml = html.ToString();
        return new MvcHtmlString(table.ToString());
    }
}

在视图中

@using YourAssembly.TableHelper
....
@Html.DisplayTableFor(m => m)

您还可以将程序集包含在您的 web.config 文件中,以便视图中不需要 @using 语句

作为旁注,&lt;table&gt; 元素用于表格数据,不应用于布局。而是考虑使用样式化的&lt;div&gt; 元素

【讨论】:

  • 这让我非常接近,所以我真的很感激。这也是一些对未来非常有用的知识。
猜你喜欢
  • 1970-01-01
  • 2014-03-07
  • 2011-09-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多