我有Action方法和View用于编辑某些项目的属性。


 [HttpPost]
 [ValidateAntiForgeryToken]
 [授权(角色=“管理员”)]
 public async Task< ActionResult>编辑(项目项目)
 {
 if(ModelState.IsValid)
 {
 db.Entry(item).State = EntityState.Modified;

等待db.SaveChangesAsync();
 return RedirectToAction(“Index”);
 }
 ViewBag.CatagorieId = new SelectList(db.Catagories,“ID”,“Name”,item.CatagorieId);
 return View(item);
 }



 和


 @model OpenOrderFramework.Models.Item& #xA; @using OpenOrderFramework.Extensions
 @ {
 ViewBag.Title =“edit”;
}

< h2>编辑< / h2>


 @using(Html.BeginForm() )
 {

 < div class =“form-horizontal”>
 < h4>汽车< / h4>
 < hr />
 @ Html.ValidationSummary(true,“”,new {@class =“text-danger”})
 @ Html.HiddenFor(model => model.ID)
 < - etc - >



 但是当我提交表单时,我收到错误

 



存储更新,插入或删除语句影响了意外的行数(0)。


我发现在行动中即使项目的真实ID不同,发布的项目的方法ID也始终为0.
 
为什么会发生?


GET操作方法:


 // GET:Items / Edit / 5
 [授权(角色=“管理员”)]
 public async Task< ActionResult>编辑(int?id)
 {
 if(id == null)
 {
返回新的HttpStatusCodeResult(HttpStatusCode.BadRequest);
 }
 Item item = await db.Items.FindAsync(id);
 if(item == null)
 {
返回HttpNotFound();
 }
 ViewBag.CatagorieId = new SelectList(db.Catagories,“ID”,“Name”,item.CatagorieId);
 return View(item);
 }
 代码>


答案 0 :(得分:1)
发布表单时,对HttpPost操作方法的http调用是一个完全独立的Http请求,实体框架无法跟踪该实体。
正如Darin在评论中提到的,在UI层中混合实体类并不是一个好主意。这使它非常紧密耦合。
您应该使用的是为视图创建和使用视图模型。 View模型只是POCO类,它特定于视图。
public class ItemViewModel
{
public int Id {set;get;}
public string Name {set;get;}
public List<SelectListItem> Categories { set;get;}
public int SelectedCategory {set;get;}
}
在您的GET操作中,从数据库中读取实体,创建视图模型的对象并将属性值设置为
public ActionResult Edit(int id)
{
var vm=new ItemViewModel { Id=id };
var item = db.Items.FirstOrDefault(s=>s.Id==id);
if(item!=null)
{
vm.Name = item.Name;
}
vm.Categories =db.Categories.Select(s=> new SelectListItem { Value=s.Id.ToString(),
Text=s.Name
}).ToList();
return View(vm);
}
您的视图将强烈输入您的视图模型
@model ItemViewModel
@using(Html.BeginForm())
{
@Html.DropdDownListFor(s=>s.SelectedCategory,Model.Categories,"Select")
@Html.HiddenFor(s=>s.Id)
@Html.TextBoxFor(s=>s.Name)
<input type="submit" />
}
在您的HttpPost操作中,从您的数据库中读取现有实体并更新您要更新的属性值。
[HttpPost]
public ActionResult Edit(ItemViewModel model)
{
if(ModelState.IsValid)
{
var item = d.Items.FirstOrDefault(s=>s.Id==model.Id);
item.Name = model.Name;
db.Entry(item).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction("Index");
}
model.Categories =db.Categories.Select(s=>
new SelectListItem {
Value=s.Id.ToString(),
Text=s.Name }).ToList();
return View(model);
}
确保在访问代码中的实体/对象之前添加足够的NULL检查。