我遇到类似于下面假设的问题。我已经多次向另一个视图添加了部分视图,但我不确定如何让它们正确绑定到视图模型等。此外,如果单个fooName错误,则验证似乎会触发每个fooName。我已经将索引添加到了viewbag中,但我还不确定如何使用它。
注意:使用MVC5.2
查看模型
public class Thing
{
public String thingName { get; set; }
public List<Foo> Foos { get; set; }
}
public class Foo
{
public String fooName { get; set; }
}
Foo View
@model Project.Models.Foo
<div class="form-horizontal">
@Html.ValidationSummary(true, "", new { @class = "text-danger" })
<div class="form-group">
<div class="col-md-12">
@Html.LabelFor(model => model.fooName, htmlAttributes: new { @class = "control-label" })
@Html.EditorFor(model => model.fooName, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.fooName, "", new { @class = "text-danger" })
</div>
</div>
</div>
Thing View
@model Project.Models.Thing
@using (Html.BeginForm())
{
@Html.AntiForgeryToken()
<div class="form-horizontal">
@Html.ValidationSummary(true, "", new { @class = "text-danger" })
<div class="form-group">
<div class="col-md-12">
@Html.LabelFor(model => model.thingName, htmlAttributes: new { @class = "control-label" })
@Html.EditorFor(model => model.thingName, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.thingName, "", new { @class = "text-danger" })
</div>
</div>
</div>
<div class="add-foo">
@* at some point add more foos with ajax, for now k.i.s.s. *@
@Html.Partial("/Views/Foo/Create.cshtml", new ViewDataDictionary { { "id", 1 } })
@Html.Partial("/Views/Foo/Create.cshtml", new ViewDataDictionary { { "id", 2 } })
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Create" class="btn btn-default" />
</div>
</div>
}
答案 0 :(得分:1)
这里的问题是Foo
部分渲染时没有更大模型的上下文。结果,您获得了一堆具有相同名称和ID的输入,即:
<input type="text" name="fooName" id="fooName" class="form-control">
...
<input type="text" name="fooName" id="fooName" class="form-control">
...
这就是为什么验证会触发所有这些因素,因为它们都是相同的。为了使部分行为正确,您需要将一些上下文传递给它。例如,如果您正在迭代可以执行的某些事情的现有实例:
@for (var i = 0; i < Model.Foos.Count; i++)
{
@Html.Partial("_Foo", Model.Foos[i])
}
根据Model.Foos[i]
位,Razor会生成正确的输入名称,如Foos[0].fooName
,Foos[1].fooName
等。
或者,您可以覆盖HtmlFieldPrefix
:
@Html.Partial("_Foo", foo1, new ViewDataDictionary { TemplateInfo = new System.Web.Mvc.TemplateInfo { HtmlFieldPrefix = "Foos[0]" } })
@Html.Partial("_Foo", foo2, new ViewDataDictionary { TemplateInfo = new System.Web.Mvc.TemplateInfo { HtmlFieldPrefix = "Foos[1]" } })
...
由于您计划通过JavaScript动态添加其他内容,因此您最好的选择是依靠Knockout或Angular等基于JavaScript数组为您渲染字段。然后,当您向该数组添加新的Foo
实例时,该库将自动向具有索引名称属性的页面添加其他字段。