如何正确绑定list
本文关键字:MVC 创建 视图 绑定 何正确 list object | 更新日期: 2023-09-27 18:06:18
我有一个类似于下面假设的问题。我已经添加了部分视图到另一个视图多次,但我不确定如何让他们正确绑定到视图模型等。此外,如果单个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视图
@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>
的视图
@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>
}
这里的问题是,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
实例时,库将自动向具有索引name属性的页面添加其他字段。