11

もう一度、「こんなはずじゃない?*!#難しい」状況に直面しました。

問題: 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 メソッドに送信されます。

4

2 に答える 2

5

これが1つのアプローチです:

@Html.DropDownListFor(model => model.Choice, 
                      ViewBag.Choices as SelectList, 
                      "-- Select an option--",
                      new { @class = "editor-textbox" })

SelectListを含めるためにViewBagを使用していることに注意してください。このようにポストバックすると、クライアントはモデルの一部として選択リスト全体をサーバーに送信しません。

コントローラコードでは、ビューバッグを設定するだけです。

ViewBag.Choices = new SelectList(....
于 2011-02-18T19:22:55.097 に答える