2009-04-03 13 views
7

カスタムモデルバインダーを作成しようとしていますが、複雑な複合オブジェクトをバインドする方法を理解しようとすると非常に困難です。複雑な複合オブジェクトのカスタムモデルバインダーヘルプ

これは私がにバインドしようとしているクラスである:任意のアイデア

public class FundModelBinder : IModelBinder 
{ 
    public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) 
    { 
     throw new NotImplementedException(); 
    } 

    public object GetValue(ControllerContext controllerContext, string modelName, Type modelType, ModelStateDictionary modelState) 
    { 
     var fund = new Fund(); 

     fund.Id = int.Parse(controllerContext.HttpContext.Request.Form["Id"]); 
     fund.Name = controllerContext.HttpContext.Request.Form["Name"]; 

     //i don't know how to bind to the list property :(
     fund.FundItems[0].Catalogue.Id = controllerContext.HttpContext.Request.Form["FundItem.Catalogue.Id"]; 
     return fund; 
    } 
} 

public class Fund 
{ 
     public int Id { get; set; } 
     public string Name { get; set; } 
     public List<FundAllocation> FundAllocations { get; set; } 
} 

と、これはカスタムバインダーを書く時、私の試みがどのように見えるかですありがとう トニー

+0

私はちょうど質問を投稿し、ついにこの同じ種類の問題に対する解決策を見つけました。興味のある方は、以下のリンクをご覧ください:[http://stackoverflow.com/questions/1077481/how-do-i-pass-a-dictionary-as-a-parameter-to-an-actionresult -method-from-jquery-a](http://stackoverflow.com/questions/1077481/how-do-i-pass-a-dictionary-as-a-parameter-to-an-actionresult-method-from- jquery-a) –

答えて

3

私はこの正確なsにあまりにも多くを費やしています最近のこと!

あなたのHTMLフォームを見ることなく、マルチ選択リストなどの選択結果を返すだけであると推測していますか?もしそうなら、水和物のFundAllocationsオブジェクトを返すのではなく、フォームがちょうど整数の束を返すだけです。それをしたいのであれば、カスタムModelBinderでは、独自のルックアップを行い、オブジェクトを自分で水和する必要があります。

ような何か:もちろん

fund.FundAllocations = 
     repository.Where(f => 
     controllerContext.HttpContext.Request.Form["FundItem.Catalogue.Id"].Contains(f.Id.ToString()); 

、私のLINQは参考用で、あなたは明らかにあなたがしたいことを、とにかくデータを取得することができます。ちなみに、私はそれがあなたの質問に答えることはできませんが、私は複雑なオブジェクトの場合、ViewModelを使用し、デフォルトのModelBinderをバインドして、必要に応じて水和私のエンティティを表すモデル。私はこれを最善の選択としたいくつかの問題がありますが、私はあなたにそれらをあげてはいませんが、望むならば推測してもらえます。

最新のHerding Code podcastは、K Scott Allen's Putting the M in MVC blog postsのようにこれに関する素晴らしい議論です。

8

実際にここにカスタムModelBinderを実装する必要がありますか?バインダーは、あなたが(それはコレクションと複雑なオブジェクトを移入することができますように)必要なものを行うことができますデフォルト:

public ActionResult SomeAction(Fund fund) 
{ 
    //do some stuff 
    return View(); 
} 

そして、あなたはhtmlのこの含まれています:

<input type="text" name="fund.Id" value="1" /> 
<input type="text" name="fund.Name" value="SomeName" /> 

<input type="text" name="fund.FundAllocations.Index" value="0" /> 
<input type="text" name="fund.FundAllocations[0].SomeProperty" value="abc" /> 

<input type="text" name="fund.FundAllocations.Index" value="1" /> 
<input type="text" name="fund.FundAllocations[1].SomeProperty" value="xyz" /> 

があなたのコントローラのアクションは、次のようになりますと言うことができます

デフォルトのモデルバインダーは、FundAllocationsリストの2つの項目を使用してファンドオブジェクトを初期化する必要があります(FundAllocationクラスの外観はわからないので、1つのプロパティ「SomeProperty」を作成しました)。これらの "fund.FundAllocations.Index"要素(デフォルトのバインダーはそれが自分自身のために使用する)を必ず含めてください。これは私がこの作業をしようとしたときに得たものです)。

+0

JonoW - 標準モデルのバインダーに関する良いドキュメントのリンクがありますか、それともソースを見ましたか? –

+0

申し訳ありません、私は同じ問題を抱えていたので、私は実際に彼のブログでPhil Haackのアドバイスを行っていました - http://haacked.com/archive/2008/10 /23/model-binding-to-a-list.aspx。 1.0でそれを行う良い方法があるかもしれません... – JonoW

+0

彼は正しいです、あなたはカスタムモデルのバインダーは必要ありません。上記のように、名前フィールドを操作することでこれを行うことができます。 – MedicineMan

関連する問題