7

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

これは私がバインドしようとしているクラスです:

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

これは、カスタムバインダーを作成しようとする私の試みがどのように見えるかです:

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

何か案は

ありがとうトニー

4

2 に答える 2

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 クラスがどのように見えるかはわかりません。そのため、単一のプロパティ "SomeProperty" を作成しました)。これらの「fund.FundAllocations.Index」要素(デフォルトのバインダーが独自の使用のために調べる)を必ず含めてください。これを機能させようとしたときに私を獲得しました)。

于 2009-04-22T10:43:18.157 に答える
3

私は最近、これとまったく同じことに多額の費用を費やしています!

HTMLフォームが表示されないのに、複数選択リストなどから選択した結果が返されるだけだと思いますか?FundAllocationsその場合、フォームはハイドレイトされたオブジェクトを返すのではなく、整数の束を返すだけです。それを実行したい場合は、カスタムModelBinderで、独自のルックアップを実行し、オブジェクトを自分でハイドレイトする必要があります。

何かのようなもの:

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

もちろん、私のLINQはほんの一例であり、必要なデータを取得できることは明らかです。ちなみに、それはあなたの質問に答えないことは知っていますが、複雑なオブジェクトについては、ViewModelを使用し、デフォルトのModelBinderをそれにバインドして、必要に応じてハイドレイトするのが最善であると判断しました。私の実体を表すモデル。私が遭遇した多くの問題がこれを最良の選択にしました。今はそれらに飽きることはありませんが、必要に応じて推定することができます。

最新のHerdingCodeポッドキャストは、 KScottAllenのPuttingtheMinMVCブログ投稿と同様にこれに関するすばらしい議論です。

于 2009-04-22T10:18:23.910 に答える