もう一度、「こんなはずじゃない?*!#難しい」状況に直面しました。
問題: MVC でフォームを使用してオブジェクトを作成したいと考えています。オブジェクトの要素の 1 つは、限られた選択肢のセットです。これは、ドロップダウン リストの完全な候補です。
しかし、モデルで SelectList を使用し、ビューでドロップダウン リストを使用してから、モデルを Create メソッドに戻そうとすると、「Missing Method Exception: No Parameterless constructor for this object」というエラーが表示されます。MVC ソース コードを調べると、モデルにバインドするには、Binder が最初にモデルを作成できる必要があり、デフォルトのコンストラクターがないため、SelectList を作成できないようです。
簡略化したコードは次のとおりです。 モデルの場合:
public class DemoCreateViewModel
{
public SelectList Choice { get; set; }
}
コントローラーの場合:
//
// GET: /Demo/Create
public ActionResult Create()
{
DemoCreateViewModel data = new DemoCreateViewModel();
data.Choice = new SelectList(new string[] { "Choice1", "Choice2", "Choice3" });
ViewData.Model = data;
return View();
}
//
// POST: /Demo/Create
[HttpPost]
public ActionResult Create(DemoCreateViewModel form)
{
try
{
// TODO: Add insert logic here
return RedirectToAction("Index");
}
catch
{
return View();
}
}
ビューの場合:
<fieldset>
<legend>Fields</legend>
<%= Html.LabelFor(model => model.Choice) %>
<%= Html.DropDownListFor(model => model.Choice, Model.Choice) %>
<p>
<input type="submit" value="Create" />
</p>
</fieldset>
これで、10 ヤード戻ってパントすることで、これを機能させることができることがわかりました。モデル バインディングをバイパスして FormCollection に戻り、自分ですべてのフィールドを検証してバインドしますが、もっと簡単な方法が必要です。つまり、これは非常に単純な要件です。MVC ModelBinding アーキテクチャ内でこれを機能させる方法はありますか? もしそうなら、それは何ですか?そうでない場合は、どうしてですか?
編集:まあ、私は顔に卵がありますが、これは他の誰かを助けるかもしれません. さらに実験を行ったところ、うまくいくと思われる簡単な解決策が見つかりました。
単純な値 (選択リストの値のタイプに応じて文字列または整数) を指定し、バインド先のモデル要素として名前を付けます。次に、選択肢の選択リストとして 2 番目の要素を指定し、別の名前を付けます。したがって、私のモデルは次のようになりました。
public class DemoCreateViewModel
{
public string Choice { get; set; }
public SelectList Choices { get; set; }
}
そして、ビューの DropDownListFor ステートメントは次のようになります。
<%= Html.DropDownListFor(model => model.Choice, Model.Choices) %>
これを行うと、フォームで行われた選択が送信ボタンによって文字列 Choice に正しくバインドされ、モデルが 2 番目の Create メソッドに送信されます。