1

ASP.NET MVC 3では、1つのMVCビューからのマスター/ディテール関係の編集と更新で問題が発生しました。ASP.NET MVC 3 - EF 4.2コードファーストマスターディテール編集

私は小さなアプリケーションを構築するためにEntity Framework 4.2コードファーストを使用しています。これは、Personクラス(Name,など)、Addressクラス(Street,ZipcodeCityなど)を使用します。

これら2つのクラスがいた:とEFコード・ファーストでモデル化互いにN関係:

public class Person 
{ 
    private List<Address> _addresses; 

    // bunch of scalar properties like ID, name, firstname 

    public virtual List<Address> Addresses 
    { 
     get { return _addresses; } 
     set { _addresses = value; } 
    } 
} 

public class Address 
{ 
    private List<Person> _people; 

    // bunch of scalar properties like AddressID, street, zip, city 

    public virtual List<Person> People 
    { 
     get { return _people; } 
     set { _people = value; } 
    } 
} 

私はうまくEF 4.2作品を使用して、データの一部のデータと検索してデータベースを手動で充填。

ASP.NET MVC PersonControllerがあります。Personをロードしていて、そのすべての現在のアドレスが含まれており、Razorビューを使用して表示しています。私は、ユーザーが既存のアドレスを変更したり更新したり、アドレスを削除したり挿入したりすることを許可します。コントローラは、このようなWCFサービスから、その人のためのデータを取得します。

public ActionResult Edit(int id) 
{ 
    Person person = _service.GetPerson(id); 
    return View(person); 
} 

と検索するときに人のアドレスが正しく入力されます。

このビューは正常に動作します。Personインスタンスのすべてのデータが正常に表示されます。

[HttpPost] 
    public ActionResult Edit(Person person) 
    { 
     if (ModelState.IsValid) 
     { 
      _service.UpdatePerson(person); 
      return RedirectToAction("Index"); 
     } 
     return View(person); 
    } 

@model DomainModel.Person 

<h2>Edit</h2> 

@using (Html.BeginForm()) { 
    @Html.ValidationSummary(true) 
    <fieldset> 
     <legend>Person</legend> 

     @Html.HiddenFor(model => model.PersonId) 

     <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> 

     .... and a few more of those scalar properties being edited.... 

     <hr/> 
     <h4>Addresses</h4> 

     @foreach (var item in Model.Addresses) 
     { 
      <tr> 
       <td> 
        @Html.EditorFor(modelItem => item.Street) 
       </td> 
       <td> 
        @Html.EditorFor(modelItem => item.ZipCode) 
       </td> 
       <td> 
        @Html.EditorFor(modelItem => item.City) 
       </td> 
      </tr> 
     } 
     <hr/> 
     <p> 
      <input type="submit" value="Save" /> 
     </p> 
    </fieldset> 
} 

しかし、私は編集中の人を保存する時にPOSTを処理しようとしているとき、私は、ビューに表示される(そしておそらく、編集)されたアドレスへのアクセスを得るように見えることはできません

この場合、person.Addressesプロパティは常にnullです。うーん....私は何が欠けているのですか? ASP.NET MVCビューでPerson-to-Addressesリレーションシップを編集してPersonの関連するAddressesを私のビューから取り戻すにはどうすればいいですか?それらをEFに渡してデータベーステーブルに戻すことはできますか? ?

答えて

2

私は、アドレスの入力フィールドに間違った名前があると思われます。

私はエディタテンプレートを使用することをお勧めします。だから、アドレスプロパティのEditorForヘルパーの1回の呼び出しでかみそりビューで@foreachループを置き換える:

<h4>Addresses</h4> 

@Html.EditorFor(x => x.Addresses) 

<hr/> 

となりました(自動的にコレクションの各要素に対してレンダリングされるアドレスのエディタテンプレートを定義~/Views/Shared/EditorTemplates/Address.cshtml):

@model Address 
<tr> 
    <td> 
     @Html.EditorFor(x => x.Street) 
    </td> 
    <td> 
     @Html.EditorFor(x => x.ZipCode) 
    </td> 
    <td> 
     @Html.EditorFor(x => x.City) 
    </td> 
</tr> 

は今、あなたが提出したときに、あなたのPersonモデル上のAddressesプロパティが正しくバインドされます。

備考エディタテンプレートは、~/Views/XXX/EditorTemplates/Address.cshtmlの中に配置することもできます。ここで、XXXは現在のコントローラです。この場合、現在のコントローラのビュー内でのみ再利用することができます(Sharedに入れることで)。

デフォルトのモデルバインダーのワイヤーフォーマットの詳細については、following articleをご覧ください。

+0

+1優れたもの - ありがとう!私はまだMVCには少し新しく、その素晴らしい機能を完全に「抱いている」わけではありません! –

2

私は次のようにブロックのためにforeachのブロックを変更することにより、所望の効果を得るだろうと考えている:もちろん

@for (var i = 0; i < Model.Addresses.Count(); i++) 
    { 
     <tr> 
      <td> 
       @Html.EditorFor(model => model.Addresses[i].Street) 
      </td> 
      <td> 
       @Html.EditorFor(model => model.Addresses[i].ZipCode) 
      </td> 
      <td> 
       @Html.EditorFor(model => model.Addresses[i].City) 
      </td> 
     </tr> 
    } 

これはアドレス収集がインデックスによってアクセス可能であることが必要です。その後、用途を

<input type="text" name="Addresses[0].Street" value="Test Street 1" /> 

モデルバインダー:forブロックが代わりのようなものを生成します

<input type="text" name="Street" value="Test Street 1" /> 

この理由はforeachブロックで結果のHTMLのようなものになるということですモデルクラスのプロパティと一致するフォームフィールド名。

両方の例は、ポイントを取得するために簡素化されており、100%正確ではありません。

+0

うん...興味深い....はい、これはうまくいくようです。任意のアイデア**なぜ@ **この動作は( 'for'ループを使って)' @ foreach'はしないのですか? –

+0

これは、MVCがhtmlをレンダリングしてモデルをバインドする方法と関係があります。 foreachを使用すると、モデルにマップできる入力フィールドの名前属性はレンダリングされません。 –

関連する問題