2011-07-23 98 views
4

所以我有這個演示項目幾乎完全工作。幫助asp.net mvc的嵌套模型綁定

public class Project 
    { 
     public int ID { get; set; } 
     [Required] 
     public string Name { get; set; } 
     public virtual ICollection<Task> Tasks { get; set; } 

    } 

    public class Task 
    { 
     public int ID { get; set; } 
     [Required] 
     public string Name { get; set; } 
     public int ProjectID { get; set; } 

     public virtual Project Project { get; set; } 

    } 

控制器

public ActionResult Edit(int id) 
     {   
      var project = db.Projects.Where(p=>p.ID==id).Single(); 
      return View(project); 
     } 

     [HttpPost] 
     public ActionResult Edit(Project project) 
     { 
      if (ModelState.IsValid) 
      { 
       var dbProject = db.Projects.Where(p => p.ID == project.ID).Single(); 

       UpdateModel(dbProject); 
       db.SaveChanges();     
       TempData["Success"] = "Modelo Valido"; 
      } 
      return RedirectToAction("Index"); 
     } 

查看//強類型的項目

@using (Html.BeginForm()) 
{ 
    @Html.ValidationSummary(true) 
    <fieldset> 
     <legend>Project</legend> 
     @Html.HiddenFor(model => model.ID) 
     <div class="editor-label"> 
      @Html.LabelFor(model => model.Name) 
     </div> 
     <div class="editor-field"> 
      @Html.EditorFor(model => model.Name) 
      @Html.ValidationMessageFor(model => model.Name) 
     </div> 
     <h1>Tasks</h1> 
     @Html.EditorFor(m => m.Tasks) 
     <p> 
      <input type="submit" value="Save" /> 
     </p> 
    </fieldset> 
} 

EditorTemplate

@model MvcApplication2.Models.Task 
<span>Task</span> 
<br /> 
    @Html.LabelFor(m => m.Name) 
    @Html.EditorFor(m => m.Name) 
    @Html.HiddenFor(m => m.ID) 
    @Html.HiddenFor(m => m.ProjectID) 
    @Html.ValidationMessageFor(m => m.Name) 

視圖顯示此

enter image description here

的問題是,當我提出的任務是填充除了虛擬財產項目一切形式......所以錯誤我得到它是

操作失敗:關係無法更改,因爲 一個或多個外鍵屬性是不可空的。當 更改爲關係時,相關的外鍵屬性 設置爲空值。如果外鍵不支持空值, 新的關係必須定義,外鍵屬性必須是 分配一個非空值,或者無關的對象必須 刪除。

這裏是我的斷點調試結果的PIC

enter image description here

請幫助。

UPDATE:

我已經改變了我的控制器行動,這

[HttpPost] 
     public ActionResult Edit(Project project) 
     { 
      if (ModelState.IsValid) 
      { 
       db.Entry(project).State = EntityState.Modified; 
       db.SaveChanges();     
       TempData["Success"] = "Modelo Valido"; 
       return RedirectToAction("Index"); 
      } 
      return View(project); 
     } 

它仍然無法正常工作。 現在對項目名稱所做的更改在數據庫中正確更新。但對任何任務名稱所做的更改都會被完全忽略。

+0

可以直接調用'db.Projects.Single(P =>頁。 ID == project.ID);'沒有'Where'。 –

回答

4

我相信@Html.EditorFor(m => m.Tasks)是生成HTML像(大約)

<label>Name</label> 
<input type="text" name="Tasks[0].Name" id="auto-gen-id"/> 
<input type="hidden" name="Tasks[0].ID" id = "auto-gen-id"/> 
<input type="hidden" name="Tasks[0].ProjectID" id = "auto-gen-id"/> 
<!--html for validation span--> 

以上,並且會爲集合中的每個任務產生在收集的第一項任務和類似HTML生成的HTML近似。唯一的區別是索引將在所有輸入的名稱屬性中增加,即Tasks[1].Name,Tasks[1].ProjectID等。此部分將實際綁定到ProjectCollection<Task> Tasks屬性,但您可以看到詳細信息部分中沒有任何輸入,如

<input type="whatever" name="Tasks[0].Project.ProjectID" .../> 
<input type="whatever" name="Tasks[0].Project.Name" ..../> 

ModelBinder的需要與適當的命名約定輸入元素的值綁定到的動作方法參數的所有屬性。出於測試目的,你可以在形式inlude在你的編輯器模板這兩條線路的任務

他們
@Html.TextBoxFor(x=>x.Project.ID) 
@Html.TextBoxFor(x=>x.Project.Name) 

輸入正確的價值觀,你將有填充這些值任務的項目屬性。但可能不是你想要的,即輸入項目信息兩次,這可能不需要(如果你使用Linq來確定它不需要)。當您調用ORM將實體附加到數據庫實體時,它會知道當前任務屬於哪個項目元素。
旁註:當你有模型綁定的問題時,請注意生成的html。生成的html將決定哪些表單值將映射到模型的哪些屬性,只要您使用默認的modelbinder即可。如果您的示例中具有主要的詳細信息類型,則變得尤爲重要。

+0

你是對的。我不想爲表單中的每個任務再次輸入項目信息...我使用EF ...真的很奇怪,像這樣的簡單任務沒有乾淨的解決方案 – ignaciofuentes

+0

EF我相信如果你附加這個實體到數據庫實體,你不必擁有項目屬性填充。 –

+0

林不知道我明白你的意思....你會介意張貼代碼示例? – ignaciofuentes