asp.net-mvc @Html.DisplayNameFor 详细模型
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/9386987/
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
@Html.DisplayNameFor for details model
提问by Alex
In my model I have an Entity
在我的模型中,我有一个实体
public class Carrier
{
public Guid CarrierId { get; set; }
public string Name { get; set; }
}
I also have a ViewModel
我也有一个 ViewModel
public class CarrierIndexViewModel
{
public IEnumerable<Carrier> Carriers { get; set; }
public PagingInfo PagingInfo { get; set; }
}
I have a strongly-typed (CarrierIndexViewModel) Index View, which is suppose to display a table of Carrier using PagingInfo.
我有一个强类型 (CarrierIndexViewModel) 索引视图,它假设使用 PagingInfo 显示 Carrier 表。
I'm trying to use Html helper to display Carrier.Name in my table's header
When I used IEnumerable as a model for this view I had
@Html.DisplayFor(model => model.Name)
我正在尝试使用 Html helper 在我的表头中显示 Carrier.Name 当我使用 IEnumerable 作为这个视图的模型时
@Html.DisplayFor(model => model.Name)
How can I get same result using my new CarrierIndexViewModel to display title for Carrier.Name?
如何使用我的新 CarrierIndexViewModel 显示 Carrier.Name 的标题获得相同的结果?
采纳答案by Jed
You can add a @using statement to your View to specify the Carrier type, then you will need to loop through your Model's Carriers property.
您可以在视图中添加 @using 语句以指定 Carrier 类型,然后您将需要遍历模型的 Carriers 属性。
Your View will look something like..
你的视图看起来像..
@model CarrierIndexViewModel
@using Carrier
@foreach(Carrier c in Model.Carriers)
{
@Html.DisplayFor(model => c.Name)
}
回答by Red Taz
I found there was no need for helper methods, extra code or looping through the collection. I just used the following:
我发现不需要辅助方法、额外代码或循环遍历集合。我只是使用了以下内容:
@Html.DisplayNameFor(model => model.Carriers.FirstOrDefault().Name)
This still works even if FirstOrDefault()would return nullbecause it's only looking for meta data, the Nameproperty itself is not accessed.
即使FirstOrDefault()会返回,这仍然有效,null因为它只是在寻找元数据,而Name不是访问属性本身。
Many thanks to @Kurianwho inspired this answer.
非常感谢@Kurian启发了这个答案。
回答by Matija Grcic
I've got a similar problem, because i don't want to type my column names by hand so i wrote a helper:
我有一个类似的问题,因为我不想手动输入我的列名,所以我写了一个助手:
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);
}
Then in the view you'll call it
然后在视图中你会调用它
@Html.DisplayColumnNameFor(Model.Carriers, m => m.Name)
Please note that you can use Display attribute which accepts Name and many other customization like Resource file etc.
请注意,您可以使用接受名称和许多其他自定义(如资源文件等)的 Display 属性。
public class Carrier
{
[Display(Name="Carrier ID")]
public Guid CarrierId { get; set; }
[Display(Name="Carrier Name")]
public string Name { get; set; }
}
回答by Deilan
Here is an approach, which is based on the originalDisplayNameForextension method and works consistent.
这是一种方法,它基于原始DisplayNameFor扩展方法并且工作一致。
An extension method for HtmlHelper:
的扩展方法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));
}
}
And that's how it could be used in a view:
这就是它在视图中的使用方式:
@Html.DisplayNameFor(m => m.Carriers, c => c.Name)
回答by daveaglick
I had a similar requirement, but I needed to get display names for properties from a different non-enumerable class so the solution from @plurby wouldn't have worked. I ended up solving this by creating a fluent call that can be used to get a new HtmlHelper for any arbitrary type. The code for the extension and adapter is:
我有一个类似的要求,但我需要从不同的不可枚举类中获取属性的显示名称,这样来自 @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);
}
}
}
You can then use this in the view like this:
然后您可以在视图中使用它,如下所示:
<td>@(Html.Adapt().For<MyOtherModel>().DisplayNameFor(m => m.SomeProperty))</td>
One of the advantages is that this approach will work for any HtmlHelper extension, not just DisplayNameFor(but keep in mind that the adapted HtmlHelper does not have any view data since that's all typed based on the model being used in the view and thus won't work in the adapted HtmlHelper).
优点之一是这种方法适用于任何 HtmlHelper 扩展,而不仅仅是DisplayNameFor(但请记住,改编后的 HtmlHelper 没有任何视图数据,因为这些数据都是基于视图中使用的模型键入的,因此不会在适应的 HtmlHelper 中工作)。

