今天我做了几个<%= Html.LabelFor(m => m.MyProperty)%>在ASP.NET MVC 2中,并使用System.ComponentModel中的[DisplayName(“Show this而不是MyProperty”)]属性。
事实证明,当我将属性放在一个被覆盖的属性上时,LabelFor似乎没有注意到。
但是,[必需]属性在覆盖属性上正常工作,生成的errormessage实际上使用了DisplayNameAttribute。
这是一些简单的示例代码,更实际的情况是,我有一个与视图模型分离的数据库模型,但为方便起见,我想从数据库模型继承,添加仅查看属性并使用UI的属性来装饰viewmodel 。
public class POCOWithoutDataAnnotations { public virtual string PleaSEOverrideMe { get; set; } } public class EditModel : POCOWithoutDataAnnotations { [required] [DisplayName("This should be as label for please override me!")] public override string PleaSEOverrideMe { get { return base.PleaSEOverrideMe; } set { base.PleaSEOverrideMe = value; } } [required] [DisplayName("This property exists only in EditModel")] public string NonOverriddenProp { get; set; } }
强类型的ViewPage< EditModel>包含:
<div class="editor-label"> <%= Html.LabelFor(model => model.PleaSEOverrideMe) %> </div> <div class="editor-field"> <%= Html.TextBoxFor(model => model.PleaSEOverrideMe) %> <%= Html.ValidationMessageFor(model => model.PleaSEOverrideMe) %> </div> <div class="editor-label"> <%= Html.LabelFor(model => model.NonOverriddenProp) %> </div> <div class="editor-field"> <%= Html.TextBoxFor(model => model.NonOverriddenProp) %> <%= Html.ValidationMessageFor(model => model.NonOverriddenProp) %> </div>
然后,标签显示为“PleaSEOverrideMe”(不使用DisplayNameAttribute),并且“查看页面时”仅使用EditModel“(使用DisplayNameAttribute)显示此属性。
如果我用空值发布,则触发此ActionMethod的验证:
[HttpPost] public ActionResult Edit(EditModel model) { if (!ModelState.IsValid) return View(model); return View("Thanks"); }
<%= Html.ValidationMessageFor(model => model.PleaSEOverrideMe)%>实际使用[DisplayName(“这应该是标签,请重写我!”)]属性,并产生默认的errortext“这应该是标签为了覆盖我!字段是必需的。
一些友好的灵魂会有一些光明吗?
解决方法
Model binding and metadata using the strongly-typed helpers looks at the declared,rather than the runtime,type of the model.我认为这是一个错误,但显然MVC团队不同意我的观点,因为我的Connect问题被关闭为“按设计”。