今天我在ASP.NET MVC 2中使用<%=Html.LabelFor(m=>m.MyProperty)%>
中的[DisplayName("Show this instead of MyProperty")]
属性并使用System.ComponentModel
中的[Required]
属性时感到困惑。
事实证明,当我将属性放在重写属性上时,LabelFor似乎没有注意到它。
但是,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; }
}
属性在重写的属性上工作正常,生成的errormessage实际上使用DisplayNameAttribute。
这是一些简单的示例代码,更现实的情况是我有一个与viewmodel分开的databasemodel,但为了方便起见,我想继承databasemodel,添加View-only属性并使用属性装饰viewmodel用户界面。
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>
包含:
[HttpPost]
public ActionResult Edit(EditModel model)
{
if (!ModelState.IsValid)
return View(model);
return View("Thanks");
}
然后标签显示为“PleaseOverrideMe”(不使用DisplayNameAttribute)和“此属性仅存在于EditModel”(<查看页面时强>使用 DisplayNameAttribute 如果我使用空值发布,则使用此ActionMethod触发验证:
<%= Html.ValidationMessageFor(model => model.PleaseOverrideMe) %>
[DisplayName("This should be as label for please override me!")]
实际上使用{{1}}属性,并生成默认的errortext “这应该是标签,请覆盖我!字段是必需的。”
有些友好的灵魂会对此有所了解吗?
答案 0 :(得分:12)
Model binding and metadata using the strongly-typed helpers looks at the declared, rather than the runtime, type of the model。我认为这是一个错误,但显然MVC团队不同意我,因为我的Connect问题被关闭为“按设计。”
答案 1 :(得分:11)
我使用[DisplayName(“Profile Name”)]遇到了这个问题,而是使用了[Display(Name = "Profile Name")]
来解决我的问题。我不确定这是否有用。
前者来自System.ComponentModel
而前者来自System.ComponentModel.DataAnnotations
。
答案 2 :(得分:3)
当我有一个强类型的部分视图接口时,我遇到了同样的问题。接口定义了DisplayName
,实现接口的类试图覆盖它。我发现让它尊重覆盖的唯一方法是键入实现类。我不得不改变视图的模型类型或强制转换。不幸的是,这完全否定了使用接口作为模型类型的好处。我猜我最终会为每个实现类提供一定程度的重复视图标记,而不会在强类型的“帮助器”中进行转换。
在这种类型的解决方法甚至远程帮助的远程机会(没有让我的希望),这是一个例子。对于尝试覆盖名称的所有可能的实现类,肯定有一些方法可以处理这个问题,但它肯定比应该更麻烦。
public interface IAddressModel {
...
[DisplayName("Province")]
public string Province { get; set; }
...
}
public class UsAddressModel : IAddressModel {
...
[DisplayName("State")]
public string Province { get; set; }
...
}
<%= Html.LabelFor(m => m.State) %> <!--"Province"-->
<%= Html.LabelFor(m => (m as UsAddressModel).State) %> <!--"State"-->
答案 3 :(得分:3)
好的,如果您不使用Required标签,我似乎找到了一种解决方法!只需使用正则表达式或长度属性来确定是否存在有效条目。希望这会有所帮助,尽管有点晚了。
[RegularExpression(@"^[1-9][0-9][0-9]$")] //validates that there is at least 1 in the quantity and no more than 999
[DisplayName("Quantity:")]
public string quantity { get; set; }
仍然有效。
答案 4 :(得分:3)
在我的情况下,我忘记了通过使用getter和setter使它成为一个属性。 而不是
public string CompanyName;
我应该用
public string CompanyName {get;set;}