Элемент ViewData с ключом "MY KEY" имеет тип "System.String", но должен иметь тип "IEnumerable <SelectListItem>",

Я пытаюсь заполнить выпадающий список из базы данных, сопоставленной с Linq-2-SQL, с использованием ASP.NET MVC 2 и продолжать получать эту ошибку.

Я так запутался, потому что я объявляю переменную типа IEnumerable<SelectListItem> во второй строке, но ошибка заставляет меня думать, что это не так. Я чувствую, что это должно быть очень просто, но я борюсь. Любая помощь приветствуется.

Вот интересные бит моего контроллера:

public ActionResult Create()
{
    var db = new DB();
    IEnumerable<SelectListItem> basetypes = db.Basetypes.Select(
        b => new SelectListItem { Value = b.basetype, Text = b.basetype });
    ViewData["basetype"] = basetypes;
    return View();
}

И вот интересные фрагменты моего представления:

<div class="editor-label">
   <%: Html.LabelFor(model => model.basetype) %>
</div>
<div class="editor-field">
   <%: Html.DropDownList("basetype") %>
   <%: Html.ValidationMessageFor(model => model.basetype) %>
</div>

Вот действие POST при отправке формы

// POST: /Meals/Create
[HttpPost]
public ActionResult Create(Meal meal)
{
    if (ModelState.IsValid)
    {
        try
        {
            // TODO: Add insert logic here
            var db = new DB();
            db.Meals.InsertOnSubmit(meal);
            db.SubmitChanges();
            return RedirectToAction("Index");
        }
        catch
        {
            return View(meal);
        }
    }
    else
    {
        return View(meal);
    }
}

Спасибо.

Ответ 1

У меня была такая же проблема, и, наконец, я получил ответ...

Проблема заключается в том, что в действии POST после отправки формы модельState недействительна или ловут ошибку в try/catch, поэтому возвращается представление. Но на этот раз представление не правильно настроено ViewData["basetype"].

Вам нужно снова заполнить его, возможно, с тем же кодом, который использовался ранее, поэтому повторите это:

var db = new DB();
IEnumerable<SelectListItem> basetypes = db.Basetypes.Select(
    b => new SelectListItem { Value = b.basetype, Text = b.basetype });
ViewData["basetype"] = basetypes;

до return View(meal) в методе [HttpPost].

именно это решит вашу проблему:

[HttpPost]
public ActionResult Create(Meal meal)
{
    if (ModelState.IsValid)
    {
        try
        {
            // TODO: Add insert logic here
            var db = new DB();
            db.Meals.InsertOnSubmit(meal);
            db.SubmitChanges();
            return RedirectToAction("Index");
        }
        catch
        {
            var db = new DB();
            IEnumerable<SelectListItem> basetypes = db.Basetypes.Select(
               b => new SelectListItem { Value = b.basetype, Text = b.basetype });
            ViewData["basetype"] = basetypes;
            return View(meal);
        }
    }
    else
    {
        var db = new DB();
        IEnumerable<SelectListItem> basetypes = db.Basetypes.Select(
            b => new SelectListItem { Value = b.basetype, Text = b.basetype });
        ViewData["basetype"] = basetypes;
        return View(meal);
    }
}

Я знаю, что этот вопрос очень старый, но я пришел сюда сегодня с той же проблемой, поэтому другие могли прийти сюда позже...

Ответ 2

Вы получите эту ошибку, если SelectList имеет значение null.

Ответ 4

Вы устанавливаете коллекцию как элемент в словаре ViewData и пытаетесь восстановить ее как свойство модели. Простое исправление было бы ссылкой на него так же, как вы его установили:

    <%var basetype = ViewData["basetype"] as IEnumerable<SelectListItem>;%>
    <div class="editor-label">
        <%: Html.Label("basetype") %>
    </div>
    <div class="editor-field">
        <%: Html.DropDownList("basetype", basetype) %>
        <%: Html.ValidationMessage("basetype") %>
    </div>

В качестве альтернативы, приведенный ниже код использует строго типизированный вид:

public class ViewModel {
   //Model properties
   public IEnumerable<SelectListItem> basetype {get;set;}
}

public ActionResult Create()
    {
        var db = new DB();
        IEnumerable<SelectListItem> basetypes = db.Basetypes.Select(b => new SelectListItem { Value = b.basetype, Text = b.basetype });
        return View(new ViewModel { basetype=basetypes });
    }

Затем в вашем строго типизированном виде:

    <div class="editor-label">
        <%: Html.LabelFor(model => model.basetype) %>
    </div>
    <div class="editor-field">
        <%: Html.DropDownListFor(model=>model.basetype) %>
        <%: Html.ValidationMessageFor(model => model.basetype) %>
    </div>

Ответ 5

Попробуйте добавить строку для имени вашего раскрывающегося списка в качестве первого параметра и вывести элемент из своих представлений:

 <%= Html.DropDownList("SomeDropdownName", (IEnumerable<SelectListItem>)ViewData["basetype"]) %>

Вот также метод расширения, который вы можете использовать, поэтому раскрывающийся список настраивается в том же стиле, что и ваши другие элементы управления:

        public static string DropDownList<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, IEnumerable<SelectListItem> selectList, string optionLabel)
        where TModel : class
    {
        string inputName = ExpressionHelper.GetInputName(expression);
        return htmlHelper.DropDownList(inputName, selectList, optionLabel);
    }

Например

<%= Html.DropDownList(x => x.BaseType, (IEnumerable<SelectListItem>)ViewData["basetype"], "")%>

Ответ 6

Если вы используете метод Html.DropDownList() - такая же ошибка может возникнуть, если элемент ViewData/Viewbag не установлен, как ответил @Peto.

Но он может быть не установлен в случае правильного элемента управления, но в основном представлении вы используете частичный вызов viw с новыми значениями ViewDataDictionary.

если у вас есть @Html.Partial("Partianame", Model,new ViewDataDictionary() { /* ... */ }), тогда ваше частичное представление не увидит данные ViewData и ViewBag, удалите параметр new ViewDataDictionary()

Ответ 7

К будущим читателям,

Сегодня я столкнулся с проблемой и не смог ее исправить. В конце концов, это оказалось очень простым. Я работал со столом + просмотр. Когда я обновил таблицу (добавил несколько колонок), я забыл обновить (отбросить и воссоздать) представление, которое вызвало эту проблему для меня. Надеюсь, это поможет кому-то.