asp.net-mvc 如何在运行时从强类型列表脚手架视图的 Display(Name=) DataAnnotation 中获取列标题?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4947854/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-08 00:52:02  来源:igfitidea点击:

How to get the column titles from the Display(Name=) DataAnnotation for a strongly typed list scaffold view at runtime?

asp.net-mvcasp.net-mvc-3razor

提问by toebens

How do I get the [Display(Name="Some Title")]DataAnnotations "Some Title" rendered in the List scaffold view's output?

如何[Display(Name="Some Title")]在 List scaffold 视图的输出中呈现 DataAnnotations “Some Title”?

I create a strongly typed list scaffold view for this class:

我为这个类创建了一个强类型列表脚手架视图:

public class CompanyHoliday
{
    [Key]
    public int Id { get; set; }

    [Required]
    [Display(Name = "Datum")]
    [DataType(System.ComponentModel.DataAnnotations.DataType.Date)]
    public DateTime Date { get; set; }

    [Required]
    [StringLength(50)]
    [Display(Name = "Feiertag Name")]
    public string Name { get; set; }
}

The view looks like this:

视图如下所示:

@model IEnumerable<Zeiterfassung.Domain.CompanyHoliday>

@{
    ViewBag.Title = "Year";
}

<h2>Year</h2>

<p>
    @Html.ActionLink("Create New", "Create")
</p>
<table>
<tr>
    <th></th>
    <th>
        Date
    </th>
    <th>
        Name
    </th>
</tr>

@foreach (var item in Model) {
<tr>
    <td>
        @Html.ActionLink("Edit", "Edit", new { id=item.Id }) |
        @Html.ActionLink("Details", "Details", new { id=item.Id }) |
        @Html.ActionLink("Delete", "Delete", new { id=item.Id })
    </td>
    <td>
        @String.Format("{0:g}", item.Date)
    </td>
    <td>
        @item.Name
    </td>
</tr>
}

</table>

However, I don't want "Date" and "Name" in the table header. I want "Datum" and "Feiertag Name" rendered there dynamically.

但是,我不希望表标题中出现“日期”和“名称”。我希望在那里动态呈现“Datum”和“Feiertag Name”。

The actual column header titles should come from the Display DataAnnotation.

实际的列标题应来自 Display DataAnnotation。

How do I do this?

我该怎么做呢?

回答by CodingWithSpike

Bit of an old topic, but I came up with an extension method to handle this.

有点老话题,但我想出了一个扩展方法来处理这个问题。

Lets say my model is:

假设我的模型是:

public class MyModel
{
    [Display(Name = "Some Property")]
    public string SomeProp { get; set; }
}

Drop this method into a static class:

将此方法放入静态类:

namespace Web.Extensions
{
    public static class HtmlHelperExtensions
    {
        public static MvcHtmlString DisplayNameFor<TModel, TProperty>(this HtmlHelper<IEnumerable<TModel>> helper, Expression<Func<TModel, TProperty>> expression)
        {
            var name = ExpressionHelper.GetExpressionText(expression);
            name = helper.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldName(name);
            var metadata = ModelMetadataProviders.Current.GetMetadataForProperty(() => Activator.CreateInstance<TModel>(), typeof(TModel), name);
            return new MvcHtmlString(metadata.DisplayName);
        }
    } 
}

Then in your View, which is taking an IEnumerable<MyModel>, you can use it like this:

然后在你的 View 中,这是一个IEnumerable<MyModel>,你可以这样使用它:

@using Web.Extensions
@model IEnumerable<MyModel>

<table>
    <tr>
        <th>
            @Html.DisplayNameFor(m => m.AvgElecCost)
        </th>

The generated HTML will be:

生成的 HTML 将是:

        <th>
            Some Property
        </th>

Hope it helps!

希望能帮助到你!

回答by AaronLS

This is the pattern I've followed. This assumes Lists are never null, but can be empty, but condition can easily be short circuited for a null list. I do like Brian's extension method though.

这是我遵循的模式。这假设列表永远不会为空,但可以为空,但条件很容易被空列表短路。不过我确实喜欢 Brian 的扩展方法。

@if (Model.BurgersList.Count > 0)
{
  var meta = Model.BurgersList.First();
   <table>
        <tr>
            <th>
                @Html.DisplayNameFor(m => meta.Title)
            </th>
            <th>
                @Html.DisplayNameFor(m => meta.HasMustard)
            </th>
         //etc....
   @foreach (var item in Model.AssignmentDefinitions)
   {
        <tr>
            <td>
                @Html.DisplayFor(m => item.Title)
            </td>
            <td>
                @Html.DisplayFor(m => item.HasMustard)
            </td>
       //etc...
   }
   </table>
}
else
{ 
    @:No burgers available.  Create(usually make this an action link)  a new one.
}

回答by yongfa365

//MVC4 has the DisplayNameFor Extensions

public static class HtmlHelperExtensions
{
    public static MvcHtmlString DisplayNameFor<TModel, TProperty>(this HtmlHelper<IEnumerable<TModel>> helper, Expression<Func<TModel, TProperty>> expression)
    {
        return DisplayNameFor(expression);
    }

    public static MvcHtmlString DisplayNameFor<TModel, TProperty>(this HtmlHelper<TModel> helper, Expression<Func<TModel, TProperty>> expression)
    {
        return DisplayNameFor(expression);
    }

    private static MvcHtmlString DisplayNameFor<TModel, TProperty>(Expression<Func<TModel, TProperty>> expression)
    {
        var metadata = ModelMetadata.FromLambdaExpression<TModel, TProperty>(expression, new ViewDataDictionary<TModel>());
        var htmlFieldName = ExpressionHelper.GetExpressionText(expression);
        string s = metadata.DisplayName ?? (metadata.PropertyName ?? htmlFieldName.Split(new char[] { '.' }).Last<string>());
        return new MvcHtmlString(HttpUtility.HtmlEncode(s));
    }
}