如何正确绑定list在MVC的创建视图中

本文关键字: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>
}

如何正确绑定list<object>在MVC的创建视图中

这里的问题是,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属性的页面添加其他字段。