2015-12-10 34 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'屬性中的值(它會告訴你有錯誤的屬性) –