Немає елемента ViewData типу "IEnumerable <SelectListItem>", який має ключ "xxx"


87

Є кілька дописів про це на Stack Overflow, але жоден з відповіддю, який, здається, вирішує проблему в моїй ситуації.

У мене є сторінка з таблицею, кожен рядок має ряд текстових полів і випадаючий список. Усі випадаючі меню повинні використовувати однакові дані SelectList, тому я встановив їх наступним чином:

Контролер

ViewData["Submarkets"] = new SelectList(submarketRep.AllOrdered(), "id", "name");

Переглянути

<%= Html.DropDownList("submarket_0", (SelectList)ViewData["Submarkets"], "(none)") %>

Я використовував саме цю установку в багатьох місцях, але чомусь саме в цьому поданні я отримую помилку:

Немає елемента ViewData типу "IEnumerable", який має ключ "submarket_0".


1
Ви спробували це? <%= Html.DropDownList("submarket_0", ((SelectList)ViewData["Submarkets"]).Items, "(none)") %>DropDownList бере IEnumerable<SelectListItem>.
LukLed

@LukLed - саме так я врешті знайшов джерело помилки :), а також інформацію з деяких інших постів! Дякую
Джимбо

<%= Html.DropDownList("submarket_0", ViewData["Submarkets"] as IEnumerable<SelectListItem>, "(none)") %>
Арвіс

Зіткнувся з цим сьогодні і виявив, що другий аргумент у моєму помічнику DropDownList був нульовим, згідно з висновком нижче від @jonathansewell.
Кен Палмер

Відповіді:


79

Гаразд, тому відповідь була отримана з деяких інших публікацій про цю проблему, і це:

Якщо ваш файл ViewDataмістить SelectListте саме ім'я, що і ваш DropDownList"submarket_0", помічник Html автоматично заповнить їх цими DropDownListданими, якщо ви не вкажете другий параметр, який у цьому випадку є джерелом SelectList.

Що сталося з моєю помилкою:

Оскільки таблиця, що містить випадаючі списки, була частково представлена, і ViewDataвона була змінена і більше не містила SelectListпосилання, на яке я посилався, HtmlHelper(замість видачі помилки) спробував знайти SelectList, який називається "submarket_0" у ViewData (GRRRR! !!), якого він ЩЕ не міг знайти, а потім викинув на це помилку :)

Будь ласка, виправте мене, якщо я помиляюсь


104
Я отримав цю помилку, оскільки моя колекція SelectListItems для випадаючого списку була нульовою, що, на мою думку, є тією ж проблемою, що і у вас.
Джонатан Сьюелл

6
Для інших, хто стикається з цією проблемою, тимчасово оберніть свій випадаючий список нульовою перевіркою, наприклад @if (ViewData ["Субмаркети"]! = Null). Якщо подання потім відображається без помилки (і без вашого випадаючого списку), ви визначите свою проблему. Помилка "немає даних про перегляд" у цьому випадку дуже оманлива.
GDB

Я наткнувся на це, використовуючи Ajax.ActionLink. Просто додайте SelectList Getдо того, ActionMethodщо містить виклик Ajax.
смерд

Так! Я змінив назву списку, який передавав у ViewData з контролера, і не змінив його у поданні. Це справді жахливо заплутане повідомлення про помилку!
neminem

1
@JonathanSewell дякую, дякую, дякую! Це була моя точна проблема.
johnw182

29

Старе питання, але ось ще одне пояснення проблеми. Ви отримаєте цю помилку, навіть якщо у вас сильно набрані представлення даних і ви не використовуєте ViewData для створення розкривного списку. Причина помилки може стати зрозумілою, коли ви подивитесь на джерело MVC :

// 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;
}

Тож якщо у вас є щось на зразок:

@Html.DropDownList("MyList", Model.DropDownData, "")

І Model.DropDownDataє нулем, MVC переглядає ваші ViewData, щоб знайти щось із іменем MyListі видає помилку, якщо в ViewData немає об’єкта з таким іменем.


1
Привіт, це теж моя проблема. Що робити, якщо список нульовий! можете щось підказати,
трансформатор

4
@transformer Найпростішим способом було б встановити Model.DropDownData порожнім списком замість null. Якщо це неможливо, ви можете змінити розмітку на бритві, щоб перевірити, чи є список нульовим, і якщо так, відтворити порожній список вибору.
hawkke

15

У мене була така ж помилка, я думаю, проблема полягає в тому, що текст помилки заплутаний , оскільки він дає помилкове ім'я ключа.

У вашому випадку слід сказати "Немає елемента ViewData типу" IEnumerable ", який має ключ" Субмаркети "".

Моєю помилкою було написання помилки в коді подання (ваш "Субмаркети"), але текст помилки звів мене з розуму.

Я публікую цю відповідь, тому що хочу сказати, що люди, які шукають цю помилку, як і я, що проблема полягає в тому, що вона не знаходить НЕЗЛІЧНЕ, а в тій вар, яка її повинна шукати (у цьому випадку "Субмаркети"), не в тому, який показав помилку ("submarket_0") .

Прийнята відповідь дуже цікава, але, як ви вже сказали, домовленість застосовується, якщо ви не вказуєте 2-й параметр, у цьому випадку він був вказаний, але змінної не знайдено (у вашому випадку, оскільки у viewdata її не було, у моєму випадку, оскільки Я неправильно написав назву var)

Сподіваюся, це допомагає!


9

Проблема в тому, що повернення повідомлення відбувається при натисканні кнопки надіслати. Тож під час опублікування даних про подання натисніть ще раз, напишіть перед поверненням View ()

ViewData["Submarkets"] = new SelectList(submarketRep.AllOrdered(), "id", "name");

3

Перевірте простір імен.

Ви можете призначити System.Web.Webpages.Html.SelectListItem у контролері замість System.Web.Mvc.SelectListItem .


1

Це теж нормально; Наприклад:
==> У файлі "NumberController":

public ActionResult Create([Bind(Include = "NumberId,Number1,Number2,OperatorId")] Number number)
{
    if (ModelState.IsValid)
    {
        ...
        ...
        return RedirectToAction("Index");
    }
    ViewBag.OperatorId = new SelectList(db.Operators, "OperatorId", 
                                "OperatorSign", number.OperatorId);                
    return View();
}

==> У файлі перегляду (Create.cshtml):

<div class="form-group">
    @Html.LabelFor(model => model.Number1, htmlAttributes: new { @class = 
                   "control-label col-md-2" })
    <div class="col-md-10">
        @Html.EditorFor(model => model.Number1, new { htmlAttributes = new { 
                        @class = "form-control" } })
        @Html.ValidationMessageFor(model => model.Number1, "", new { @class = 
                                   "text-danger" })
    </div>
</div>

Тепер, якщо ми видалимо це твердження:

ViewBag.OperatorId = new SelectList(db.Operators, "OperatorId", "OperatorSign", number.OperatorId);

зі зворотного боку наступного твердження (у нашому контролері):

return View();

ми побачимо цю помилку:

Немає елемента ViewData типу "IEnumerable", який має ключ "OperatorId".

* Тож будьте впевнені в існуючому з цих тверджень. *


0

Для мене проблема, яка спричинила цю помилку, виникла, коли я зберігав новий рядок у базі даних, але поле було нульовим. У дизайні таблиці бази даних це поле НЕ НУЛЕВО. Отже, коли я намагався зберегти новий рядок із нульовим значенням для ненульового поля, Visual Studio викинув цю помилку. Таким чином, я переконався, що полю було присвоєно значення, і проблема була виправлена.


0

У моєму випадку я виявив, що помилково встановив метод публікації як приватний. після зміни приватного на державний.

[HttpPost]
private async Task<ActionResult> OnPostRemoveForecasting(){}

перейти

[HttpPost]
public async Task<ActionResult> OnPostRemoveForecasting(){}

Зараз працює нормально.


0

Причина не суперечить синтаксису, а не неправильному використанню об’єктів. Життєвий цикл об’єктів у ViewData, ViewBag та View Life Cycle коротший, ніж у сеансі. Дані, визначені у формувальниках, будуть втрачені після запиту-відповіді (якщо спробувати отримати доступ після запиту-відповіді, ви отримаєте винятки). Отже, формувачі підходять для передачі даних між View & Controller, тоді як останні для зберігання тимчасових даних. Тимчасові дані повинні зберігатися в сеансі, щоб мати доступ до них багато разів.


-1

У моєму випадку стався конфлікт у просторах імен, я маю:

using System.Web.Mvc;

і

using System.Collections.Generic;

Я явно хочу використовувати Mvc, тому я оголосив його як:

new System.Web.Mvc.SelectList(...)

1
Якщо мої очі не обманюють мене, немає SelectListв System.Collections.Generic.
Ерік Філіпс,
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.