为什么action方法出错参数?

时间:2015-12-29 21:11:23

标签: asp.net-mvc razor actionmethod

我有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-horizo​​ntal”>
 < 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);
 }
  



1 个答案:

答案 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检查。