避免在ASP.NET MVC中重复查看代码

时间:2017-11-16 02:42:44

标签: asp.net-mvc-4 razor

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

给出类似List<string> propertyNames的内容,在这个表中,我想在这样的结构中输出DisplayNameFor和属性的值:

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

我必须在partial中执行几次,因为不同的属性对应于部分中的不同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>
    }
}

如何使这项工作得到改善?

1 个答案:

答案 0 :(得分:3)

模型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语句

另请注意,<table>元素用于表格数据,不应用于布局。而是考虑使用样式化的<div>元素