未设置DisplayName时DisplayNameForModel与DisplayNameFor无法显示模型名
问题解答
你没有遗漏什么,这是ASP.NET MVC/Razor的默认设计逻辑:
为什么DisplayNameFor/DisplayNameForModel对模型本身返回空?
- 当针对模型的属性调用
DisplayNameFor时,框架默认会提取属性的名称(比如Bar); - 但当针对模型类型本身调用
DisplayNameFor(model => model)或DisplayNameForModel()时,框架只会从[DisplayName]或[Display]特性中读取显示名称,没有这些特性时就返回空字符串。
而当Foo作为其他类的属性存在时,你调用的DisplayNameFor实际是指向父类的这个属性(而非Foo类型本身),所以框架会返回属性的名称(比如父类里的属性叫Foo,就会显示"Foo"),这和直接用Foo作为模型的场景逻辑完全不同。
无需耦合特性的解决方案
不想给模型加特性绑定UI逻辑的话,有两种简单的实现方式:
直接在视图中获取类型名称:
修改视图标题部分:<h1>Details @Model.GetType().Name</h1>后续要做国际化时,只需要把类型名称映射到资源文件,比如从资源类读取
@Resources.ModelNames.Foo,完全不用改动模型代码。自定义HtmlHelper扩展方法:
封装类型名称的获取逻辑,后续还能扩展支持资源读取:public static class HtmlHelperExtensions { public static MvcHtmlString DisplayNameForType<TModel>(this HtmlHelper<TModel> html) { var typeName = typeof(TModel).Name; // 后续国际化时替换为资源读取逻辑即可 return MvcHtmlString.Create(typeName); } }视图中调用方式:
<h1>Details @Html.DisplayNameForType()</h1>
关于提交修复请求
这不属于框架bug,是既定的设计决策——框架默认不把类名作为模型的显示名称,而是要求通过特性显式声明。如果希望调整这个设计,可以向.NET官方代码仓库提交功能建议,说明你的使用场景和诉求,但不会被当作“修复”处理。
内容的提问来源于stack exchange,提问作者jbatista
相关产品推荐
相关产品推荐

