2015-12-10 40 views
0

我有一个代码的第一个项目MVC 5.简化的,我有以下型号:EF 6 ModelState.IsValid是跳投假的ID

public class Person 
{ 
    public int Id { get; set; } 
    public string ItemCode { get; set; } 
    public string Description { get; set; } 
} 

在我看来,我有一个文本框的表:

@model IList<ItemApp.Models.Item> 

@{ 
    ViewBag.Title = "Index"; 
} 

<h2>Index</h2> 

@using(Html.BeginForm("Process", "Items", FormMethod.Post)) 
{ 
    @Html.AntiForgeryToken() 

    <button type="button" class="btn btn-primary" id="btnAddRow">AddRow</button> 
    <input type="submit" class="btn btn-success" value="process"/> 
<table class="table"> 
    <tr> 
     <th> 
      ItemCode 
     </th> 
     <th> 
      Description 
     </th> 
    </tr> 

     @for (int i = 0; i < Model.Count(); i++) 
     { 
      <tr> 
       <td> 
        <input type="hidden" value="@i" name="Index" /> 

        @Html.TextBoxFor(item => item[i].ItemCode) 
       </td> 
       <td> 
        @Html.TextBoxFor(item => item[i].Description) 
       </td> 

      </tr> 
     } 
    <tr> 
     <td> 
      <input type="hidden" value="4" name="Index" /> 
      <input type="hidden" name="[4].Id" /> 
      <input type="text" name="[4].ItemCode" /> 
     </td> 
     <td> 
      <input type="text" name="[4].Description" /> 
     </td> 
    </tr> 

</table> 

} 

正如您在我看来所见,我添加了一行。运行te项目时,前3行通过数据库填充。当我在最后一行输入值并提交表单时,可以看到我的操作接收到一个Item对象列表(Count = 4)。我的过程操作如下所示:

[HttpPost] 
[ValidateAntiForgeryToken] 
public ActionResult Process(List<Item> items) 
{ 
    if(ModelState.IsValid) 
    { 
     foreach(var item in items) 
     {    
      if(item.Id != 0) 
      { 
       db.Entry(item).State = System.Data.Entity.EntityState.Modified; 
      } 
      else 
      { 
       db.Items.Add(item); 
      } 

      db.SaveChanges(); 
     } 

     return RedirectToAction("Index"); 
    } 

    return RedirectToAction("Index"); 
} 

问题是我的ModelState.IsValid返回false。这是因为最后一个(新进入的)行的Id = 0。 我想要的是提交表单,更新已经在数据库中的所有项目并添加一个新项目。

+0

我假设这个班级的名字实际上是'Item',而不是'Person'根据您的视图和控制器方法 –

回答

2

ModelState是不是无效的,因为Id=0(零是有效的值int)其无效的,因为你回来后null为第4项。您需要将您的视图更改为

<input type="hidden" name="[4].Id" value="0"/> 

所以回发Id=0(或者你可以简单地忽略元素和值将是0当您提交表单,因为这是为int默认值)

但是,由于您不会为每个现有项目的Id属性生成表单控件,因此这些也将具有Id=0,这意味着您将再次将现有项目添加到数据库,而不是更新它们。在循环中,你还需要

@Html.HiddenFor(item => item[i].Id) 

但是你的代码是不灵活的,如果你有确切3现有的项目将只工作,而且永远只允许您添加一个新的项目。建议您查看答案herehere以动态(和删除)集合中的项目。

+0

我错过了'value =“0”'部分。这样,调试器向我显示了项目[4] .Id的0,但它并没有真正的价值。我完全知道代码不灵活。那将是我的下一步。 – kwv84

+0

是的,它会显示'0',因为模型联编程序试图将其设置为'null'(但不能),所以您只能看到默认值。当你调试时,你需要检查'ModelState'属性中的值(它会告诉你有错误的属性) –