2011-07-23 17 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

問題は、私はタスクは、仮想プロジェクトのプロパティを除くすべてが移入されているフォームを送信する...ので、エラー私は得るとき、それは操作が失敗した

であるということである。関係 1つまたは複数の外部キープロパティがnullにできないために変更できませんでした。リレーションシップに が変更された場合、関連する外部キープロパティはNULL値に設定された です。外部キーがNULL値をサポートしていない場合は、 新しい関係を定義する必要があります。外部キーのプロパティーは に別のNULL以外の値を割り当てる必要があります。または、関連しないオブジェクトは を削除する必要があります。ここで

助けてください

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); 
     } 

に私のコントローラのアクションを変更しました。 これで、プロジェクトの名前に対する変更がデータベースで正しく更新されました。タスク名の変更は完全に無視されます。私は@Html.EditorFor(m => m.Tasks)は、上記の(約)

<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を生成していると信じて

+0

(うまくいけば、一時的にそれをやって)私は現在、午前方法を確認するために私の現在のコードをリファクタリングする方法については、この質問を参照してください。 ID == project.ID); ''なし '。 –

答えて

4

はおおよそのHTMLがコレクションの最初のタスクの生成と同様のHTMLがコレクション内の各タスクのために生成されますです。唯一の違いは、すべての入力の名前属性でインデックスが増えます。つまり、Tasks[1].Name,Tasks[1].ProjectIDなどです。この部分は実際にはCollection<Task> TasksプロパティのProjectにバインドされますが、詳細部分には

などの入力はありません
<input type="whatever" name="Tasks[0].Project.ProjectID" .../> 
<input type="whatever" name="Tasks[0].Project.Name" ..../> 

Modelbinderは、アクションメソッドパラメータのすべてのプロパティに値をバインドするために、適切な命名規則で入力要素が必要です。テストの目的のためには、タスク

のためのあなたのエディタテンプレートに次の2行
@Html.TextBoxFor(x=>x.Project.ID) 
@Html.TextBoxFor(x=>x.Project.Name) 

形で彼らのために入力の適切な値をinludeすることができますし、タスクのプロジェクトプロパティは、これらの値が移入されます。しかし、あなたが望むものではないかもしれません。つまり、プロジェクト情報を2回入力してください。これは必要ではないかもしれません。エンティティをdbエンティティにアタッチするためにORMを呼び出すと、現在のタスクがどのプロジェクト要素に属しているかがわかります。
サイドノート:モデルバインディングに問題がある場合は、常に生成されたhtmlに注意してください。生成されたhtmlは、デフォルトのモデルバインダーを使用している限り、どのフォーム値をモデルのどのプロパティにマップするかを指示します。あなたの例のようにマスターの詳細な種類のシナリオを持っている場合は、特に重要になります。

+0

あなたは正しいです。私はフォームの各タスクのプロジェクト情報を再度入力したくない...私はEFを使用しています...これは、このような単純なタスクは、クリーンなソリューションを持っていることは本当に奇妙です – ignaciofuentes

+0

私はあなたがこれを添付すればエンティティからdbエンティティに、Projectプロパティを設定する必要はありません。 –

+0

私はあなたが意味することを理解していますかわかりません....コードサンプルを投稿してもよろしいですか? – ignaciofuentes

関連する問題