web-dev-qa-db-ja.com

ASP.NET MVC-Html.DropDownList-ViewData.Modelで値が設定されていません

ASP.NET MVCで遊んだばかりで、次の状況に遭遇しました。バグのように感じますが、そうでない場合は説明をいただければ幸いです:)

ビューにはかなり基本的なものが含まれています

<%=Html.DropDownList("MyList", ViewData["MyListItems"] as SelectList)%>
<%=Html.TextBox("MyTextBox")%>

モデルを使用しない場合、値と選択されたアイテムは期待どおりに設定されます。

//works fine
public ActionResult MyAction(){
  ViewData["MyListItems"] = new SelectList(items, "Value", "Text"); //items is an ienumerable of {Value="XXX", Text="YYY"}

  ViewData["MyList"] = "XXX"; //set the selected item to be the one with value 'XXX'
  ViewData["MyTextBox"] = "ABC"; //sets textbox value to 'ABC'

  return View();
}

しかし、モデルを介してロードしようとすると、テキストボックスに期待どおりの値が設定されますが、ドロップダウンは選択されたアイテムセットを取得しません。

//doesnt work
public ActionResult MyAction(){
  ViewData["MyListItems"] = new SelectList(items, "Value", "Text"); //items is an ienumerable of {Value="XXX", Text="YYY"}

  var model = new {
    MyList = "XXX", //set the selected item to be the one with value 'XXX'
    MyTextBox = "ABC" //sets textbox value to 'ABC'
  }

  return View(model);
}

何か案は?私の現在の考えは、おそらくモデルを使用するとき、viewdata(これは正常に機能します)を使用してモデルでselectlistを渡す代わりに、SelectListコンストラクターで選択された項目を設定することに制限されているということです-これは利点がありますコードを少しクリーンアップする方法-なぜこの方法が機能しないのか不思議に思っています...

提案をありがとう

17
chrisb

ヘミングとホーンの束の後、次のコード行に要約されます

if (ViewData.ModelState.TryGetValue(key, out modelState))

つまり、MVCはViewData Dictionary <>オブジェクトのみを参照して値を解決しようとし、ViewData.Modelオブジェクトに移動しません。

バグか、制限か、設計上の決定かはわかりません。ただし、次の方法で修正できます。

<%= Html.TextBox("MyTextBox", ViewData.Model.MyTextBox) %>
5
Todd Smith

実際には、Html.DropDownList()nullを渡すだけです。
私はまったく同じ問題を抱えていて、Reflectorを使用してMVCソースコードを調べました。

System.Web.Mvc.Extensions.SelectExtensionsクラスのSelectInternal()メソッドでは、selectListパラメータがかどうかを確認しますnullかどうか。 nullとして渡された場合、SelectListを適切に検索します。

これが「コードビハインド」です。

ViewData["MyDropDown"] = new SelectList(selectListItems,
                             "Value",
                             "Text",
                             selectedValue.ToString()
                         );

HTMLビューのコードは次のとおりです。

<%= Html.DropDownList("MyDropDown", null,
        "** Please Select **",
        new { @class = "my-select-css-class" }
    ) %>

注:私はASP.NET MVC 2.0(ベータ版)を使用しています。

更新ノート:2012年1月31日

過去3年間ASP.NET MVCを広範囲に使用した後、私は Html.EditorFor()メソッド 詳細。

[List Items]anonymousオブジェクトとして同じプロパティ名Html.EditorFor()メソッドへのモデルのプロパティとして。

<%= Html.EditorFor(
    m => m.MyPropertyName,
    new { MyPropertyName = Model.ListItemsForMyPropertyName }
) %>

詳細については、 別のスレッドでの私の回答 を参照してください。

23
stun

selectListコレクションを作成するときに、コントローラーアクションで選択した値を設定してみてください。

ViewData ["AddressTypeId"] = new SelectList(CustomerService.AddressType_List()、 "AddressTypeId"、 "Name"、myItem.AddressTypeId);

2
IamNotaRobot

私は明らかにここに遅れています。しかし、誰かがこの問題に遭遇した場合に備えて、このコメントを追加したかったのです。

MVC 2では、次のようにして項目を選択できます...

public ActionResult Edit(int id)
        {
            Team team = _db.TeamSet.First(m => m.TeamID == id);
            var fanYear = from c in _db.FanYearSet select c;
            ViewData["FantasyYear"] = new SelectList(fanYear, "YearID", "FantasyYear", team.FanYearReference.EntityKey.EntityKeyValues[0].Value);
            var league = from c in _db.LeagueSet select c;
            ViewData["League"] = new SelectList(league, "LeagueID", "League_Name", team.LeaguesReference.EntityKey.EntityKeyValues[0].Value);

            return View(team);
        }

4番目のパラメーターは値を取り、ドロップダウンリストで必要な値を選択します。私の例では、teamというテーブルがあり、fanYearおよびleagueというテーブルに関係が設定されています。

私が最初に編集しているチームを取得し、次にファンタジー年とリーグ用のドロップダウンリストを作成していることがわかります。チームの年とリーグを決定するために、エンティティリファレンスを使用する必要がありました。

それをそこに出したかっただけです。私はこれを行う例を見つけることができませんでした。

2
Michael