我遇到一个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个步骤的wizzard,其中每个步骤都是紧急联系表单。
最后,有一个全局提交按钮,可将所有模型数据发送到我的控制器:
[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对象,但我的紧急联系人列表中只包含第一个填充在wizzard中的内容!另外两个是空的!
有谁可以告诉我为什么?
答案 0 :(得分:1)
您的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>
现在您正在创建多个表单。如果你想创建一个大的表单而不是你需要创建一个表单,在一个表单中只包含多个制表符和字段集。
答案 1 :(得分:1)
可能,您没有携带数据。每个请求都是独立的,因此它必须发布先前请求或中的所有数据,您必须以某种方式保留以前发布的数据,将其存储在数据库或会话中。
很难从代码中确切地知道这是如何运作的。通过第三次联系,用户是否会在屏幕上看到3组完整的联系人字段?换句话说,第一次通过时,只有一组字段。第二次,有第一次填充第一次,最后第三次,有两组填充数据,一组空集准备好由用户填写?
如果是这种情况,那么我说这是非常糟糕的用户界面。真的最好放弃在服务器之间来回发布所有帖子,只需一次渲染所有三个集合,这样用户就可以一次性输入它们。
如果情况并非如此,并且每次只显示一组字段,为什么还有一个循环呢?您还需要在请求之间以某种方式保留其他联系人。