模型绑定列表在 Asp MVC 中不起作用

List of Models binding not working in Asp MVC

我在使用 MVC 时遇到了一个问题。我想在同一个视图中使用不同的模型(创建一个大表格)。我正在使用 ViewModel 方法在内部收集我的模型。

视图模型:

 public class EditByUserObjectsVM
    {
        public Person Person {set; get; }
        public List<EmergencyContact> EmergencyContacts {set; get; }

    }

我的观点是这样的(紧急联系人方面):

<div class="tab-content">
    @for (var i = 0; i < Model.EmergencyContacts.Count(); i++)
    {

        <div class="tab-pane" id="tab@(i + 1)" name="@(i + 1)">
            <form class="form-horizontal">
                <fieldset>
                    @Html.HiddenFor(model => model.EmergencyContacts[i].ID)
                    <div class="form-group">
                        @Html.LabelFor(model => model.EmergencyContacts[i].LastName, htmlAttributes: new { @class = "control-label col-md-2" })
                        <div class="col-md-10">
                            @Html.EditorFor(model => model.EmergencyContacts[i].LastName, new { htmlAttributes = new { @class = "form-control" } })
                            @Html.ValidationMessageFor(model => model.EmergencyContacts[i].LastName, "", new { @class = "text-danger" })
                        </div>
                    </div>

                    <div class="form-group">
                        @Html.LabelFor(model => model.EmergencyContacts[i].FirstName, htmlAttributes: new { @class = "control-label col-md-2" })
                        <div class="col-md-10">
                            @Html.EditorFor(model => model.EmergencyContacts[i].FirstName, new { htmlAttributes = new { @class = "form-control" } })
                            @Html.ValidationMessageFor(model => model.EmergencyContacts[i].FirstName, "", new { @class = "text-danger" })
                        </div>
                    </div>

                    <div class="form-group">
                        @Html.LabelFor(model => model.EmergencyContacts[i].Phone, htmlAttributes: new { @class = "control-label col-md-2" })
                        <div class="col-md-10">
                            @Html.EditorFor(model => model.EmergencyContacts[i].Phone, new { htmlAttributes = new { @class = "form-control" } })
                            @Html.ValidationMessageFor(model => model.EmergencyContacts[i].Phone, "", new { @class = "text-danger" })
                        </div>
                    </div>

                    <div class="form-group">
                        @Html.LabelFor(model => model.EmergencyContacts[i].PersonalMail, htmlAttributes: new { @class = "control-label col-md-2" })
                        <div class="col-md-10">
                            @Html.EditorFor(model => model.EmergencyContacts[i].PersonalMail, new { htmlAttributes = new { @class = "form-control" } })
                            @Html.ValidationMessageFor(model => model.EmergencyContacts[i].PersonalMail, "", new { @class = "text-danger" })
                        </div>
                    </div>

                    <div class="form-group">
                        @Html.LabelFor(model => model.EmergencyContacts[i].Adress, htmlAttributes: new { @class = "control-label col-md-2" })
                        <div class="col-md-10">
                            @Html.EditorFor(model => model.EmergencyContacts[i].Adress, new { htmlAttributes = new { @class = "form-control" } })
                            @Html.ValidationMessageFor(model => model.EmergencyContacts[i].Adress, "", new { @class = "text-danger" })
                        </div>
                    </div>

                    <div class="form-group">
                        @Html.LabelFor(model => model.EmergencyContacts[i].PostalCode, htmlAttributes: new { @class = "control-label col-md-2" })
                        <div class="col-md-10">
                            @Html.EditorFor(model => model.EmergencyContacts[i].PostalCode, new { htmlAttributes = new { @class = "form-control" } })
                            @Html.ValidationMessageFor(model => model.EmergencyContacts[i].PostalCode, "", new { @class = "text-danger" })
                        </div>
                    </div>

                    <div class="form-group">
                        @Html.LabelFor(model => model.EmergencyContacts[i].Town, htmlAttributes: new { @class = "control-label col-md-2" })
                        <div class="col-md-10">
                            @Html.EditorFor(model => model.EmergencyContacts[i].Town, new { htmlAttributes = new { @class = "form-control" } })
                            @Html.ValidationMessageFor(model => model.EmergencyContacts[i].Town, "", new { @class = "text-danger" })
                        </div>
                    </div>

                    <div class="form-group">
                        @Html.LabelFor(model => model.EmergencyContacts[i].Link, htmlAttributes: new { @class = "control-label col-md-2" })
                        <div class="col-md-10">
                            @Html.EditorFor(model => model.EmergencyContacts[i].Link, new { htmlAttributes = new { @class = "form-control" } })
                            @Html.ValidationMessageFor(model => model.EmergencyContacts[i].Link, "", new { @class = "text-danger" })
                        </div>
                    </div>
                </fieldset>
            </form>
        </div>
    }        
    <ul class="pager wizard">
        <li class="previous"><a href="javascript:void(0);">Retour</a></li>
        <li class="next"><a href="javascript:void(0);">Suivant</a></li>
    </ul>
</div>

我们的想法是创建一个包含 3 个步骤的向导,其中每个步骤都是要填写的紧急联系表。

最后,有 1 个全局提交按钮将所有模型数据发送到我的控制器:

        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult EditByUser(EditByUserObjectsVM editByUserObjectsVM)
        {
            if (ModelState.IsValid)
            {
                try
                {
                    db.Entry(editByUserObjectsVM.Person).State = EntityState.Modified;
                    db.SaveChanges();
                    editByUserObjectsVM.EmergencyContacts[0].PersonSerial = editByUserObjectsVM.EmergencyContacts[1].PersonSerial = editByUserObjectsVM.EmergencyContacts[2].PersonSerial = editByUserObjectsVM.Person.Serial;
                    db.Entry(editByUserObjectsVM.EmergencyContacts[0]).State = EntityState.Modified;
                    db.SaveChanges();
                    db.Entry(editByUserObjectsVM.EmergencyContacts[1]).State = EntityState.Modified;
                    db.SaveChanges();
                    db.Entry(editByUserObjectsVM.EmergencyContacts[2]).State = EntityState.Modified;
                    db.SaveChanges();

                    return RedirectToAction("Index");
                }
                catch (DbEntityValidationException e)
                {
                    var newException = new FormattedDbEntityValidationException(e);
                    throw newException;
                }
            }
            ViewBag.ResponsibleSerial = new SelectList(db.People, "Serial", "LastName", editByUserObjectsVM.Person.ResponsibleSerial);
            return View(editByUserObjectsVM.Person);
        } 

当我点击提交按钮时,我在控制器中收到了我的 ViewModel 对象,但是我的紧急联系人列表只包含向导中填写的第一个!其他两个为空!

谁能告诉我为什么?

你的 form 应该在 forloop 之外。

<form class="form-horizontal">
    <div class="tab-content">
        @for (var i = 0; i < Model.EmergencyContacts.Count(); i++)
        {
            <div class="tab-pane" id="tab@(i + 1)" name="@(i + 1)">
                <fieldset>
                    <!-- ... -->
                </fieldset>
            </div>
        }  
        <ul class="pager wizard">
            <li class="previous"><a href="javascript:void(0);">Retour</a></li>
            <li class="next"><a href="javascript:void(0);">Suivant</a></li>
        </ul> 
    </div>
</form>

现在您正在创建多个表单。如果您想创建一个大表单,则只需要创建一个表单,其中包含多个选项卡和字段集。

您可能没有携带数据。每个请求都是独立的,因此它必须 post 来自先前请求的所有数据 您必须以某种方式保留先前 posted 的数据,要么将其存储在数据库或会话。

很难从所提供的代码中准确判断这是如何运作的。通过第三次联系,用户是否会在屏幕上看到 3 套完整的联系方式?换句话说,第一次通过时,只有一组字段。第二次通过,有两套第一次填写,最后第三次,有两套有填充数据和一套空的准备由用户填写?

如果是这样的话,我会说这很糟糕UI。真的,最好放弃所有 post 在服务器之间来回切换,一次渲染所有三个集合,这样用户就可以一次性输入它们。

如果情况并非如此,并且每次您都只显示一组字段,那为什么会有一个循环?您还需要在请求之间以某种方式保留其他联系人。