& ldquo; System.InvalidOperationException: «Нет элемента ViewData типа« IEnumerable & lt; SelectListItem & gt; ', который имеет ключ «Описание». & Rdquo; [Дубликат]

Вы можете сделать так1, потому что:

  1. x и y уже находятся в области видимости ( [basic.scope.class] / 1 ).
  2. Поскольку вы получаете ссылку после запуска конструктора ( [class.cdtor] / 1 ), а память для y уже получена ( [основной. life] / 7 ), эта ссылка может быть привязана к y.

Использование этой ссылки внутри составного оператора конструктора (после инициализации члена целиком) также отлично , Это потому, что y считается инициализированным, а x теперь относится к объекту, чье время жизни началось.


1 - Существует предостережение для юристов-языков. Технически ссылка должна быть привязана к действительному объекту ( [dcl.ref] / 5 ), что означает тот, чье время жизни было начато. Однако, как и в случае с Core Language issue 363 , ожидается, что он будет работать! Проблемная формулировка и возможное решение обсуждаются в проблеме основного языка 453 (любезно предоставлено @ T.C. В удаленном комментарии). В стандарте есть ошибка, но ваш код должен быть хорошо сформирован, и реализации, как правило, знают об этом.

69
задан Stephen Muecke 19 December 2015 в 02:26
поделиться

1 ответ

Ошибка означает, что значение CategoryList равно нулю (и в результате метод DropDownListFor() ожидает, что первый параметр имеет тип IEnumerable<SelectListItem>).

Вы не генерируете вход для каждого свойства каждого SelectListItem в CategoryList (и не должен), поэтому никакие значения для SelectList не отправляются в метод контроллера, и поэтому значение model.CategoryList в методе POST равно null , Если вы вернете представление, вы должны сначала переназначить значение CategoryList, как и в методе GET.

public ActionResult Create(ProjectVM model)
{
    if (!ModelState.IsValid)
    {
        model.CategoryList = new SelectList(db.Categories, "ID", "Name"); // add this
        return View(model);
    }
    // Save and redirect
}

Чтобы объяснить внутреннюю работу (исходный код может быть см. здесь )

Каждая перегрузка DropDownList() и DropDownListFor() в конечном итоге вызывает следующий метод

private static MvcHtmlString SelectInternal(this HtmlHelper htmlHelper, ModelMetadata metadata,
  string optionLabel, string name, IEnumerable<SelectListItem> selectList, bool allowMultiple,
  IDictionary<string, object> htmlAttributes)

, который проверяет, есть ли selectList (второй параметр из @Html.DropDownListFor()) является null

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

, который, в свою очередь, вызывает

private static IEnumerable<SelectListItem> GetSelectData(this HtmlHelper htmlHelper, string name)

, который оценивает первый параметр @Html.DropDownListFor() (в данном случае CategoryID )

....
o = htmlHelper.ViewData.Eval(name);
....
IEnumerable<SelectListItem> selectList = o as IEnumerable<SelectListItem>;
if (selectList == null)
{
    throw new InvalidOperationException(String.Format(CultureInfo.CurrentCulture, 
        MvcResources.HtmlHelper_WrongSelectDataType,
        name, o.GetType().FullName, "IEnumerable<SelectListItem>"));
}

Поскольку свойство CategoryID является typeof int, оно не может быть передано в IEnumerable<SelectListItem>, и генерируется исключение (которое определено в файле MvcResources.resx как)

<data name="HtmlHelper_WrongSelectDataType" xml:space="preserve">
    <value>The ViewData item that has the key '{0}' is of type '{1}' but must be of type '{2}'.</value>
</data>
67
ответ дан Stephen Muecke 31 August 2018 в 13:05
поделиться
Другие вопросы по тегам:

Похожие вопросы: