キーとして int を含み、値としてオブジェクトのリストを含む Dictionary を含むフォームを投稿できません。
もともとこれは単なるオブジェクトのリストでしたが、それはうまく機能し、タイプは次のとおりでした:
List<MyObject> Fields
作業マークアップは
Fields_{0}__Property1
ここで、{0} はオブジェクトのインデックスです。オブジェクトのリストをポストバックするために、次のような隠しフィールドでオブジェクトをレンダリングしました。
@Html.HiddenFor(m => m.Property1, new { Name = string.Format("Fields[{0}].Property1", Model.Index), @id = string.Format("Fields_{0}__Property1", Model.Index) })
これはうまくいきました。ただし、リストの代わりに辞書があり、リストは辞書の中にあります。
現在、タイプは次のとおりです。
Dictionary<int, List<MyObject>>.
Html.HiddenFor を使用してディクショナリをレンダリングするときに期待される形式をテストしたので、次の必要な形式で隠しフィールドを追加しました。
@Html.HiddenFor(m => m.Property1, new { Name = string.Format("Fields[{0}][{1}].Property1", Model.Index, Model.Position), @id = string.Format("Fields_{0}__{1}__Property1", Model.Index, Model.Position) })
現在、フィールドIDは
Fields_{0}__{1}__Property1
ここで、{0} は辞書のキー、{1} はリスト内のオブジェクトのインデックスです。
しかし、ポストバックで私は今得る
[InvalidCastException: Specified cast is not valid.]
System.Web.Mvc.CollectionHelpers.ReplaceDictionaryImpl(IDictionary`2 dictionary, IEnumerable`1 newContents) +131
MVC は、この複雑なオブジェクトのフィールドをビューにレンダリングするのに十分なほどスマートですが、ポストバックしたときにそれらをビューモデルに戻すほどスマートではないと推測しています。
ここで同様の問題を抱えているこの別の人を見つけ、辞書を使用せずに複雑なオブジェクトを作成することで解決しました。ただし、システム全体を書き直す必要のない、より迅速な方法があるかどうか疑問に思っています。
何か案は?
アップデート
DefaultModelBinder のソース コードを取得して調整することで解決しました。ここでソースを見つけました。すべての高度な機能と検証規則を他のすべての要素に適用したいので、独自の Binder を作成しませんでした。DefaultModelBinder をコンパイルして動作させると、ディクショナリが複雑なアイテムのキャストに失敗していた部分を見つけ、問題を解決するカスタム Dictionary update メソッドを書きました