@ Html.DisplayNameFor获取详细信息模型

时间:2012-02-21 23:32:52

标签: asp.net-mvc razor html-helper

在我的模型中,我有一个实体

public class Carrier
{
public Guid CarrierId { get; set; }
public string Name { get; set; }
}

我也有一个ViewModel

public class CarrierIndexViewModel
{
public IEnumerable<Carrier> Carriers { get; set; }
public PagingInfo PagingInfo { get; set; }
}

我有一个强类型(CarrierIndexViewModel)索引视图,它假设使用PagingInfo显示Carrier表。

我正在尝试使用Html帮助程序在我的表头中显示Carrier.Name 当我使用IEnumerable作为这个视图的模型时,我有 @Html.DisplayFor(model => model.Name)

如何使用我的新CarrierIndexViewModel显示Carrier.Name的标题?

5 个答案:

答案 0 :(得分:38)

我发现不需要辅助方法,额外的代码或循环遍历集合。我刚刚使用了以下内容:

@Html.DisplayNameFor(model => model.Carriers.FirstOrDefault().Name)

即使FirstOrDefault()返回null,这仍然有效,因为它只查找元数据,但不会访问Name属性本身。

非常感谢@Kurian启发了这个答案。

答案 1 :(得分:17)

我遇到了类似的问题,因为我不想手工输入我的列名,所以我写了一个帮手:

public static IHtmlString DisplayColumnNameFor<TModel, TClass, TProperty>
    (this HtmlHelper<TModel> helper, IEnumerable<TClass> model,
    Expression<Func<TClass, TProperty>> expression)
{ 
    var name = ExpressionHelper.GetExpressionText(expression);
    name = helper.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldName(name);
    var metadata = ModelMetadataProviders.Current.GetMetadataForProperty(
        () => Activator.CreateInstance<TClass>(), typeof(TClass), name);

    return new MvcHtmlString(metadata.DisplayName);
}

然后在视图中你会称之为

@Html.DisplayColumnNameFor(Model.Carriers, m => m.Name)

请注意,您可以使用接受名称的显示属性和许多其他自定义项,如资源文件等。

public class Carrier
{
  [Display(Name="Carrier ID")]
  public Guid CarrierId { get; set; }
  [Display(Name="Carrier Name")]
  public string Name { get; set; }
}

答案 2 :(得分:8)

您可以在View中添加@using语句以指定Carrier类型,然后您需要遍历Model的Carriers属性。

您的视图看起来像......

@model CarrierIndexViewModel
@using Carrier

@foreach(Carrier c in Model.Carriers)
{
 @Html.DisplayFor(model => c.Name)
}

答案 3 :(得分:3)

这是一种方法,它基于原始 DisplayNameFor扩展方法,工作一致

HtmlHelper的扩展方法:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Web;
using System.Web.Mvc;

public static class HtmlHelperExtensions
{
    public static MvcHtmlString DisplayNameFor<TModel, TEnumerable, TValue>(this HtmlHelper<TModel> html, Expression<Func<TModel, IEnumerable<TEnumerable>>> enumerableExpression, Expression<Func<TEnumerable, TValue>> valueExpression)
    {
        var metadata = ModelMetadata.FromLambdaExpression(valueExpression, new ViewDataDictionary<TEnumerable>());
        string displayName = metadata.DisplayName ?? metadata.PropertyName ?? ExpressionHelper.GetExpressionText(valueExpression).Split('.').Last();
        return new MvcHtmlString(HttpUtility.HtmlEncode(displayName));
    }
}

以及如何在视图中使用它:

@Html.DisplayNameFor(m => m.Carriers, c => c.Name)

答案 4 :(得分:2)

我有类似的要求,但我需要从不同的非可枚举类获取属性的显示名称,因此@plurby的解决方案不起作用。我最终通过创建一个流畅的调用来解决这个问题,该调用可用于为任意类型获取新的HtmlHelper。扩展和适配器的代码是:

public static class HtmlHelpers
{
    public static HtmlHelperAdapter<TModel> Adapt<TModel>(this HtmlHelper<TModel> helper)
    {
        return new HtmlHelperAdapter<TModel>(helper);
    }

    public class HtmlHelperAdapter<TModel>
    {
        private readonly HtmlHelper<TModel> _helper;

        public HtmlHelperAdapter(HtmlHelper<TModel> helper)
        {
            _helper = helper;
        }

        public HtmlHelper<TNewModel> For<TNewModel>()
        {
            return new HtmlHelper<TNewModel>(_helper.ViewContext, new ViewPage(), _helper.RouteCollection);
        }
    }
}

然后你可以在视图中使用它:

<td>@(Html.Adapt().For<MyOtherModel>().DisplayNameFor(m => m.SomeProperty))</td>

其中一个优点是这种方法适用于任何HtmlHelper扩展,而不仅仅是DisplayNameFor(但请记住,改编后的HtmlHelper没有任何视图数据,因为所有视图数据都是根据所使用的模型进行输入的在视图中因此不适用于改编的HtmlHelper)。

相关问题