Элемент 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.
Ответ 3
Я только что столкнулся с этой проблемой, и эта статья мне помогла - http://odetocode.com/Blogs/scott/archive/2010/01/18/drop-down-lists-and-asp-net-mvc.aspx
Скорее всего, это приведет к тому, что ваша коллекция будет повторно заполнена после po
Ответ 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
К будущим читателям,
Сегодня я столкнулся с проблемой и не смог ее исправить. В конце концов, это оказалось очень простым. Я работал со столом + просмотр. Когда я обновил таблицу (добавил несколько колонок), я забыл обновить (отбросить и воссоздать) представление, которое вызвало эту проблему для меня.
Надеюсь, это поможет кому-то.