我对ViewModel上的编辑视图有一点问题。当我第一次将我的编辑视图发布到服务器时,它需要使用添加了数据库ID的相同ViewModel再次返回编辑视图。
这是相应控制器中的Edit方法:
[HttpPost]
public ActionResult Edit(InvoiceDetailsViewModel invoice) {
using (var context = new HyperContext(WebSecurity.CurrentUserId)) {
if (ModelState.IsValid) {
if (invoice.ID == 0) {
var dbItem = Mapper.Map<eu.ecmt.RecruitmentDatabase.Models.Invoice>(invoice);
context.Invoices.Add(dbItem);
context.SaveChanges();
var newInvoice = Mapper.Map<InvoiceDetailsViewModel>(dbItem);
FillViewBag(context, newInvoice);
newInvoice.Description = "TEST";
return PartialView(newInvoice);
}
else {
context.Entry(Mapper.Map<eu.ecmt.RecruitmentDatabase.Models.Invoice>(invoice)).State = System.Data.EntityState.Modified;
context.SaveChanges();
return Content(Boolean.TrueString);
}
}
FillViewBag(context, invoice);
return PartialView(invoice);
}
}
此处的相关部分是invoice.ID
为0的位置,发票将保存到数据库以获取ID并返回到编辑视图。
在那个视图中,我为初学者提供了这些内容:
@model eu.ecmt.RecruitmentDatabase.ViewModels.InvoiceDetailsViewModel
@using (Html.BeginForm("Edit", "Invoice", FormMethod.Post, new { id = "invoices-edit-form" })) {
@Html.ValidationSummary(true)
<script type="text/javascript">
$(document).ready(function () {
//$("#tabs").tabs();
InitProfileUI();
});
</script>
if (Model.ID != 0) {
<script type="text/javascript">
$(document).ready(function () {
LoadList('/InvoiceDetail/List/@Model.ID', '', 'invoice-details');
});
</script>
}
<fieldset>
<legend>Edit contract</legend>
@Html.HiddenFor(m => m.ID)
@Html.HiddenFor(m => m.InvoiceNumber)
@Html.HiddenFor(m => m.Created)
@Html.HiddenFor(m => m.CreatedBy)
@Html.HiddenFor(m => m.Modified)
@Html.HiddenFor(m => m.ModifiedBy)
首次渲染此视图时,包含LoadList
调用的脚本元素不在输出中。发布表单并使用更新的视图模型呈现视图时,该元素位于输出中。但是,包含发票ID的隐藏字段仍然显示0.因此,实质上,这里发生的是ViewData字典中的Model对象是正确的版本,表达式中使用的对象似乎成为另一个更老的版本。
有人想解释这一点,并指出我正确的方向吗?
答案 0 :(得分:1)
根据this post,这似乎是设计行为。
总结:HTMLHelper将首先使用POST中的值,然后它将使用实际模型中的值。在控制器方法中从ModelState中删除它们可以解决这个问题:
[HttpPost]
public ActionResult Edit(InvoiceDetailsViewModel invoice) {
using (var context = new HyperContext(WebSecurity.CurrentUserId)) {
if (ModelState.IsValid) {
if (invoice.ID == 0) {
ModelState.Remove("ID");
ModelState.Remove("Created");
ModelState.Remove("CreatedBy");
ModelState.Remove("Modified");
ModelState.Remove("ModifiedBy");
var dbItem = Mapper.Map<eu.ecmt.RecruitmentDatabase.Models.Invoice>(invoice);
context.Invoices.Add(dbItem);
context.SaveChanges();
invoice = Mapper.Map<InvoiceDetailsViewModel>(dbItem);
FillViewBag(context, invoice);
return PartialView(invoice);
}
else {
context.Entry(Mapper.Map<eu.ecmt.RecruitmentDatabase.Models.Invoice>(invoice)).State = System.Data.EntityState.Modified;
context.SaveChanges();
return Content(Boolean.TrueString);
}
}
FillViewBag(context, invoice);
return PartialView(invoice);
}
}