Как List безопасно преобразуется в список выбора в представлении

#c# #asp.net #asp.net-mvc

#c# #asp.net #asp.net-mvc

Вопрос:

Я следил за вопросом, где в OP было что-то вроде этого

 [HttpGet]
public  ActionResult Index() {
   var options = new List<SelectListItem>();

   options.Add(new SelectListItem { Text = "Text1", Value = "1" });
   options.Add(new SelectListItem { Text = "Text2", Value = "2" });
   options.Add(new SelectListItem { Text = "Text3", Value = "3" });

   ViewBag.Status = options;

   return View();
}
  

А затем в представлении удалось сделать что-то вроде этого

 @Html.DropDownList("Status", ViewBag.Status as SelectList)
  

Я ожидал, что результатом приведения будет null , и я так и заявил. Меня исправили, что он должен работать, и это было продемонстрировано с помощью .net fiddle. К моему удивлению, выпадающий список был заполнен элементами.

Мой вопрос: как получается, что при выполнении в представлении List<SelectListItem> безопасно преобразуется в SelectList

Комментарии:

1. Я думаю, что приведение возвращает null. Это работает, потому что первый параметр @Html.DropDownList имеет то же имя, что и свойство ViewData / ViewBag (т.Е. «Статус»). Просто удалите приведение из рассматриваемой скрипки. Это будет работать. dotnetfiddle.net/KRxJhN

2. Хороший улов! Я думаю, что это ответ

3. @AndreiOlariu Это должно быть ответом

4. Чтобы подтвердить @AndreiOlariu с помощью консольного приложения: dotnetfiddle.net/codVBw Я даже не мог использовать as для приведения, пока не сделал список перечислимым.

5. Но это работает в скрипке: @Html.DropDownList("Status")

Ответ №1:

Это был хороший вопрос. Я изучил этот вопрос дальше, и, действительно, если selectList параметр равен null, то name параметр используется для поиска ключа ViewData .

Я основываю это на http://aspnetwebstack.codeplex.com/SourceControl/changeset/view/5cb74eb3b2f3#src/System.Web.Mvc/Html/SelectExtensions.cs

Они даже добавили комментарий:

 private static MvcHtmlString SelectInternal(this HtmlHelper htmlHelper, ModelMetadata metadata, string optionLabel, string name, IEnumerable<SelectListItem> selectList, bool allowMultiple, IDictionary<string, object> htmlAttributes)
{
    ...
    // If we got a null selectList, try to use ViewData to get the list of items.
    if (selectList == null)
    {
       selectList = htmlHelper.GetSelectData(name);
       ...
  

И позже name используется:

 private static IEnumerable<SelectListItem> GetSelectData(this HtmlHelper htmlHelper, string name)
{
    object o = null;
    if (htmlHelper.ViewData != null)
    {
        o = htmlHelper.ViewData.Eval(name);
    }
    ...
  

Хороший вопрос @Nkosi. Я понятия не имел, что это возможно.