我的应用程序中有一个显示供应商列表的索引视图。我还想添加一个小表单以在该页面上添加新项目。创建表单将发布到"创建"操作。我的模型类包含供应商列表,以及名为 NewVendor 的单个供应商的一个属性。
public IEnumerable<SoftwareVendor> Vendors { get; set; }
public SoftwareVendor NewVendor { get; set; }
SoftwareVendor
类具有验证属性。它是一个实体框架类。
制作发布到"创建"操作的表单很容易:
@using (Html.BeginForm( "Create", "Vendor" )) {
@Html.ValidationSummary(true)
<fieldset>
<legend>New Software Vendor</legend>
<div class="editor-label">
@Html.LabelFor(model => model.NewVendor.Name)
</div>
<div class="editor-field">
@Html.EditorFor( model => model.NewVendor.Name )
@Html.ValidationMessageFor( model => model.NewVendor.Name )
</div>
<br />
<input type="submit" value="Create" />
</fieldset>
}
这篇文章很好,客户端验证也可以。但是,默认的"创建"操作采用SoftwareVendor
的实例,并在表单集合中查找名为"Name"的键。相反,上面的表格发布"NewVendor.Name"。
我可以通过在 @Html.EditorFor
中指定模板和字段名称来解决此问题。
@Html.EditorFor( model => model.NewVendor.Name, "string", "Name" )
现在,"创建"操作很高兴,因为正在接收"名称"值。但是,验证消息已损坏,因为它仍在查找名为"NewVendor.Name"的字段,并且似乎无法覆盖此字段。
<span class="field-validation-valid" data-valmsg-for="NewVendor.Name" data-valmsg-replace="true"></span>
我缺少一些简单的东西来完成这项工作吗?
以下是我可以解决此问题的操作列表:
- 让我的"创建"操作采用我的索引模型的实例,而不是软件供应商。不过,我仍然有一个传统的"创建"视图,我不想这样做。
- 不要让我的创建操作采用任何参数。相反,手动查看表单键并从"名称"或"NewVendor.Name"中提取名称,以存在者为准。
- 让"创建"操作同时采用两个模型类,并检测哪个模型类已正确填充。这很像#2,但我正在检查非空值的属性,而不是检查表单集合。
- 弄清楚如何制作一个模型绑定器来执行 #2 正在做的事情。这似乎过于复杂,我将在许多页面中遇到此问题,所以我希望有更简单的方法。
- 使用 javascript 进行发布而不是表单提交,这样我就可以控制我要发布的确切字段名称。这有效,但我更愿意利用 HTML 表单,因为这就是它的用途。
- 使用
EditorFor
重载指定字段名称,并手动创建验证消息。 - 在
HtmlHelper
上为可以覆盖字段名称的新ValidationMessageFor
编写我自己的扩展方法。
在这些选项中,#2 或 #5 是我认为我会选择的选项,除非有更好的方法。
嗯,这奏效了:
@Html.EditorFor( model => model.NewVendor.Name, "string", "Name" )
@Html.ValidationMessage( "Name" )
由于我对上述代码的唯一真正问题是损坏的验证消息,这似乎解决了我的问题。我仍然很好奇总体上是否有更好的解决方案。