これがチームが修正すべきバグだと思わない場合は、少なくともMSDNでドキュメントを改善する必要があります。紛らわしいのは、この貧弱な文書からです。でMSDN、それはパラメータの説明 名前をとして、
Type: System.String
The name of the form field to return.
これは、生成される最終的なhtmlがそのパラメーターを選択入力の名前として使用することを意味します。しかし、それは実際にはそれ以上のものを意味します。
デザイナーは、ユーザーがビューモデルを使用してドロップダウンリストを表示し、同じビューモデルへのポストバックを使用すると想定していると思います。しかし、多くの場合、私たちは実際にその仮定を守っていません。
上記の例を使用して、
public class Person {
public int Id { get; set; }
public string Name { get; set; }
}
仮定に従う場合、このドロップダウンリスト関連ビューのビューモデルを定義する必要があります
public class PersonsSelectViewModel{
public string SelectedPersonId,
public List<SelectListItem> Persons;
}
ポストバックすると、選択した値のみがポストバックされるため、モデルのプロパティSelectedPersonIdにポストバックする必要があると想定します。つまり、Html.DropDownListの最初のパラメーター名は「SelectedPersonId」である必要があります。したがって、デザイナーは、ビューにモデルビューを表示するとき、モデルのプロパティSelectedPersonIdがそのドロップダウンリストのデフォルト値を保持する必要があると考えます。List <SelectListItem> Personsが既にSelectedフラグを設定してどのフラグが選択/デフォルトであるかを示していたとしても、tml.DropDownListはそれを実際に無視して、独自のIEnumerable <SelectListItem>を再構築し、名前に基づいてデフォルト/選択されたアイテムを設定します。
これがasp.net mvcのコードです
private static MvcHtmlString SelectInternal(this HtmlHelper htmlHelper, ModelMetadata metadata,
string optionLabel, string name, IEnumerable<SelectListItem> selectList, bool allowMultiple,
IDictionary<string, object> htmlAttributes)
{
...
bool usedViewData = false;
// If we got a null selectList, try to use ViewData to get the list of items.
if (selectList == null)
{
selectList = htmlHelper.GetSelectData(name);
usedViewData = true;
}
object defaultValue = (allowMultiple) ? htmlHelper.GetModelStateValue(fullName, typeof(string[])) : htmlHelper.GetModelStateValue(fullName, typeof(string));
// If we haven't already used ViewData to get the entire list of items then we need to
// use the ViewData-supplied value before using the parameter-supplied value.
if (defaultValue == null && !String.IsNullOrEmpty(name))
{
if (!usedViewData)
{
defaultValue = htmlHelper.ViewData.Eval(name);
}
else if (metadata != null)
{
defaultValue = metadata.Model;
}
}
if (defaultValue != null)
{
selectList = GetSelectListWithDefaultValue(selectList, defaultValue, allowMultiple);
}
...
return tagBuilder.ToMvcHtmlString(TagRenderMode.Normal);
}
そのため、コードは実際にさらに進んで、モデル内だけでなくビューデータ内でも名前を検索しようとします。名前を見つけるとすぐに、selectListを再構築し、元のSelectedを無視します。
問題は、多くの場合、実際にはそのように使用しないことです。1つまたは複数の項目が選択されたtrueが設定されたselectListをスローするだけです。
もちろん、解決策は簡単です。モデルにもビューデータにもない名前を使用してください。一致が見つからない場合は、元のselectListが使用され、元のSelectedが有効になります。
しかし、私はまだMVCがもう1つの条件を追加することでそれを改善すべきだと思います
if ((defaultValue != null) && (!selectList.Any(i=>i.Selected)))
{
selectList = GetSelectListWithDefaultValue(selectList, defaultValue, allowMultiple);
}
元のselectListにすでに1つのSelectedがある場合、なぜそれを無視するのですか?
ただ私の考え。