Asp.net MVCのバグのように見えるか、単に何か間違ったことをしていることに気づきました。私は現在1.0を使用しているため、これは2.0リリースで対処される予定です。しかし、どちらにしても、ここに行きます。
ビューモデルに、ドロップダウンリストの宣言されたIDと同じ名前のプロパティがある場合、選択されたアイテムは無視され、レンダリングされたhtmlには何も選択されません。私が何か間違ったことをしたかどうかはわかりませんが、IDの名前を変更すると問題は解決します。私は例を単純化しました、それが明確であることを望みます、さもなければ私に知らせてください。
宣言されたIDがモデル内の私のリストと同じ名前である私のビューです:
<table border="0" cellpadding="0" cellspacing="0">
<tr>
<td>
<%= Html.DropDownList("IsMultipleServicers", Model.IsMultipleServicers) %>
</td>
</tr>
</table>
そしてレンダリングされたHTML
<table border="0" cellpadding="0" cellspacing="0">
<tr>
<td>
<select id="IsMultipleServicers" name="IsMultipleServicers">
<option value="false">No</option>
<option value="true">Yes</option>
</select>
</td>
</tr>
</table>
これで少し変更できます。宣言されたIDを別のものに変更します。
これが私の見解です:
<table border="0" cellpadding="0" cellspacing="0">
<tr>
<td>
<%= Html.DropDownList("MultipleServicers", Model.IsMultipleServicers) %>
</td>
</tr>
</table>
そしてレンダリングされたhtml:
<table border="0" cellpadding="0" cellspacing="0">
<tr>
<td>
<select id="IsMultipleServicers" name="IsMultipleServicers">
<option value="false">No</option>
<option selected="selected" value="true">Yes</option>
</select>
</td>
</tr>
</table>
リストの2番目の要素になる選択オプションが表示されることに注意してください。
ここにすべてを結びつけるための私のViewModelがあります:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
namespace MVCProject.Models.ViewModels.Service
{
public class ServiceViewModel : ViewModel
{
public List<SelectListItem> IsMultipleServicers { get; set; }
}
}
これが私のアクションです:
[AcceptVerbs(HttpVerbs.Get)]
public virtual ActionResult Service()
{
return View(new ServiceViewModel()
{
IsMultipleServicers = BuildBooleanSelectList(true)
};
}
private List<SelectListItem> BuildBooleanSelectList(bool isTrue)
{
List<SelectListItem> list = new List<SelectListItem>();
if (isTrue)
{
list.Add(new SelectListItem() { Selected = false, Text = "No", Value = "false" });
list.Add(new SelectListItem() { Selected = true, Text = "Yes", Value = "true" });
}
else
{
list.Add(new SelectListItem() { Selected = true, Text = "No", Value = "false" });
list.Add(new SelectListItem() { Selected = false, Text = "Yes", Value = "true" });
}
return list;
}
問題はDropDownList
オーバーロードに関する混乱だと思います:
Html.DropDownList(string name)
は、name
のビューモデルプロパティを探し、_IEnumerable<SelectListItem>
_と入力します。同じ名前のフォーム投稿値がない限り、リストから選択されたアイテム(_SelectListItem.Selected == true
_)を使用します。
Html.DropDownList(string name, IEnumerable<SelectListItem> selectList)
はselectList
のアイテムを使用しますが、選択した値は使用しません。ビューモデル(または投稿データ)のname
を解決し、_SelectListItem.Value
_と照合することにより、選択されたものが見つかります。値が見つからない(またはnull)場合でも、SelectListItemsのリストから選択した値を使用しません。
コードは2番目のオーバーロードを使用しますが、存在しない「value」プロパティ(「MultipleServicers」)を指定します。
問題を解決するには、最初のオーバーロードを使用します:
_<%= Html.DropDownList("IsMultipleServicers") %>
_
または、_string MultipleServicers
_プロパティをビューモデルに追加し、コントローラーに設定します。初期表示、投稿表示、投稿データのビュー/投稿モデルへのマッピングに関するいくつかの問題を回避するため、このソリューションをお勧めします。
_public class ServiceViewModel : ViewModel
{
public string MultipleServicers { get; set; }
public List<SelectListItem> IsMultipleServicers { get; set; }
}
_
次に、HTMLについて:
_<%= Html.DropDownList(Model.MultipleServicers, Model.IsMultipleServicers) %>
_
この手法は、MVC2にもマッピングされます。
_<%= Html.DropDownListFor(x => x.MultipleServicers, Model.IsMultipleServicers) %>
_
Html.DropDownList(string name、IEnumerable selectList)オーバーロードを使用して、この同じ問題に遭遇しました。モデルには、ドロップダウンリストの名前と同じ名前のプロパティがあるようです。この場合、MVCはIEnumerableの各エントリのSelectedプロパティよりもModelのプロパティ値を優先しました。
解決策は、プロパティ名と一致しないドロップダウンリストの名前を使用することでした。別の解決策は、モデルとビューステートを無視し、代わりに常に選択したプロパティを尊重する独自の拡張メソッドを記述することです。
DropDownListヘルパーは、モデルからデフォルト値を取得します。最初のケースでは、名前に対応するモデルの値はSelectListです。これはリスト内のどのアイテムとも一致しないため、リストであるため、値は選択されません。 2番目の例では、モデルにはその名前のプロパティが含まれていないため、モデルの値は使用できず、デフォルトでSelectList自体に示された状態になります。通常、選択した値のモデルのプロパティ(これがデフォルトになります)と、リストの潜在的な値を表す別のプロパティがあります。