2009-02-27 42 views
12

私はmvcアプリケーションでいくつかのバインディングを使用したいと思っています。私はネストされたプロパティが自動的にasp.net mvcのRC1リリースでデフォルトのモデルのバインダーによってバインドされていないことがわかります。asp.netのネストされたプロパティのモデルバインドmvc

public class Contact{ 
    public int Id { get; set; } 
    public Name Name { get; set; } 
    public string Email { get; set; } 
} 

としてNameが定義されています:

using(Html.BeginForm()){ 
    Html.Textbox("Name.Forename", Model.Name.Forename); 
    Html.Textbox("Name.Surname", Model.Name.Surname); 
    Html.Textbox("Email", Model.Email); 
    Html.SubmitButton("save", "Save"); 
} 

私のコントローラのアクションは次のように定義されています。私の見解は、の線に沿って定義されている

public class Name{ 
    public string Forename { get; set; } 
    public string Surname { get; set; } 
} 

私は、次のクラス構造を持っています:

public ActionResult Save(int id, FormCollection submittedValues){ 
    Contact contact = get contact from database; 
    UpdateModel(contact, submittedValues.ToValueProvider()); 

    //at this point the Name property has not been successfully populated using the default model binder!!! 
} 

プロパティは正常にバインドされましたが、Name.ForenameまたはName.Surnameプロパティはバインドされません。これはデフォルトのモデルのバインダーを使用して動作する必要がありますか、私は何か間違ってやっている場合、または動作しない場合、モデルオブジェクトのネストされたプロパティをバインドするために自分のコードをロールバックする必要がある

答えて

9

この問題は、プロパティのName接頭辞が原因であると思います。私はそれを2つのモデルとして更新し、2番目のモデルのプレフィックスを指定する必要があると思います。パラメータからFormCollectionを削除し、組み込み値プロバイダを使用し、考慮するプロパティのホワイトリストを指定するUpdateModelというシグネチャを使用したことに注意してください。非常に興味深い

public ActionResult Save(int id) 
{ 
    Contact contact = db.Contacts.SingleOrDefault(c => c.Id == id); 

    UpdateModel(contact, new string[] { "Email" }); 
    string[] whitelist = new string[] { "Forename", "Surname" }; 
    UpdateModel(contact.Name, "Name", whitelist); 
} 
+0

これはすばらしい、ありがとうtvanfosson。 –

+0

SingleOrDefaultはlamda式で直接呼び出すことができます –

+0

@PhilippMあなたは絶対的に正しいです、更新された! – tvanfosson

4

ザッツあなたは、私は大きな成功を収めてこれを使用してい

public ActionResult Save(int id, Contact contact) 
{ 
    //contact here would contain the nested values. 
} 

をやっていればいるため。 私は、あなたは何とか2つのContactオブジェクトを一緒に同期させることができると思います。

私は、UpdateModelとパラメータへのバインディングが同じ呼び出しをバックグラウンドで使用していると思います。注:問題を再現しようとしていません。

3

POSTでビューモデル全体ではなく名前をバインドするには、モデルバインダーに接頭辞を使用するよう指示する必要があります。これは、BindAttributeを使用して行われます。

public ActionResult AddComment([Bind(Prefix = "Name")] Name name) 
{ 
    //do something 
} 
関連する問題