C# 没有具有键“PestType”的“IEnumerable<SelectListItem>”类型的 ViewData 项
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/18781878/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
There is no ViewData item of type 'IEnumerable<SelectListItem>' that has the key 'PestType'
提问by mikey
I am learning MVC and Entity Framework, so pleas bear my questions... I am trying to create a drop down menu for a property (Enum type) for my model class SinglePest Here is the model:
我正在学习 MVC 和实体框架,所以请回答我的问题......我正在尝试为我的模型类 SinglePest 创建一个属性(枚举类型)的下拉菜单这是模型:
public class SinglePest
{
public int SinglePestId { get; set; }
public PestType PestType { get; set; } // here is my problem
public string Alias { get; set; }
public string TechName { get; set; }
public string Markings { get; set; }
public string SerialNumber { get; set; }
public SourceType SourceType { get; set; }
//virtual property
public Source Source { get; set; }
}
Here is PestType:
这是害虫类型:
public enum PestType
{
Dog,
Cat,
Fox,
Rabbit,
Rat
}
This is the controller:
这是控制器:
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create (//(SinglePest singlepest)
[Bind(Include= "Alias, TechName, SerialNumber, PestType, Markings")] SinglePest singlepest)
{
try
{
if (ModelState.IsValid)
{
db.SinglePests.Add(singlepest);
db.SaveChanges();
return RedirectToAction("Index");
}
}
catch (DataException /* dex */)
{
ModelState.AddModelError("", "Unable to save changes, try again, if problem persits contact your administrator");
}
//ViewBag.SerialNumber = new SelectList(db.Sources, "SerialNumber", "SerialNumber", singlepest.SerialNumber);
return View(singlepest);
}
And here is the View where I get the error (There is no ViewData item of type 'IEnumerable' that has the key 'PestType'.) :
这是我收到错误的视图(没有具有键“PestType”的“IEnumerable”类型的 ViewData 项。):
<div class="editor-label">
@Html.LabelFor(model => model.PestType, "Pest Type")
</div>
<div class="editor-field">
@Html.DropDownList("PestType", String.Empty) // here is the error
@Html.ValidationMessageFor(model => model.PestType.ToString())
</div>
Now I have seen some posts about displaying enum, but I can't figure out a solution for my problem. Could please someone give me some piece of advice on how to fix it?
现在我看到了一些关于显示枚举的帖子,但我找不到解决我的问题的方法。请有人给我一些有关如何解决它的建议吗?
Thank you for your time!
感谢您的时间!
采纳答案by christiandev
You have @Html.DropDownList("PestType", String.Empty)
, but the second param needs to be an IEnumerable<T>
. You will need the list of your pest in the model, and then use model.Pests
for example where Pets is an IEnumerable
.
你有@Html.DropDownList("PestType", String.Empty)
,但第二个参数需要是一个IEnumerable<T>
. 您将需要模型中的害虫列表,然后使用model.Pests
例如 Pets 是IEnumerable
.
EDIT: Based on comment...
编辑:基于评论...
But I want to display just the various types of pest (Dog, Cat, etc) not all the pests that are in my database
但我只想显示各种类型的害虫(狗、猫等),而不是我数据库中的所有害虫
OK, are these categorised, could you write something like (hand written so check syntax)..
好的,这些是分类的,你能写点类似的东西吗(手写这样检查语法)。
var pests = (from _context.Pests.Where(p => p.CategoryId == 1) select p.PestName).ToList();
If you need to get a IEnumerable for the enum (since I'm not sure what the DB looks like), you can use...
如果您需要为枚举获取 IEnumerable(因为我不确定数据库的外观),您可以使用...
Enum.GetValues(typeof(PestType))
.OfType<PestType>()
.Where(p => p == ??);
回答by pingoo
Currently your model only contains a place to store the value and not a Array/IEnumerable to populate the drop down from.
目前,您的模型仅包含一个存储值的位置,而不包含用于填充下拉列表的 Array/IEnumerable。
First add an IEnumerable to your model:
首先将 IEnumerable 添加到您的模型中:
public class SinglePest
{
public int SinglePestId { get; set; }
public IEnumerable<PestType> Pests { get; set; }
public PestType PestType { get; set; }
public string Alias { get; set; }
public string TechName { get; set; }
public string Markings { get; set; }
public string SerialNumber { get; set; }
public SourceType SourceType { get; set; }
//virtual property
public Source Source { get; set; }
}
And in your controller:
在您的控制器中:
public ActionResult Create()
{
var model = new SinglePest();
model.Pests = Enum.GetValues(typeof(PestType)).Cast<PestType>()
return View(model);
}
And your view:
而你的观点:
@Html.DropDownListFor(m => m.PestType, Model.Pests);
Sorry if theres any errors I've written this from memory...
对不起,如果有任何错误,我是凭记忆写的...
回答by mikey
I found this post on DropDownListFor enumsIt seems it is solving my problem.
我在DropDownListFor enums上找到了这篇文章 看来它正在解决我的问题。
so I have just changed the view with this new piece of code:
所以我刚刚用这段新代码更改了视图:
<div class="editor-label">
@Html.LabelFor(model => model.PestType, "Pest Type")
</div>
<div class="editor-field">
@Html.DropDownListFor(model => model.PestType, new SelectList(Enum.GetValues(typeof( MvcTrackingSystem.Enums.PestType))))
@Html.ValidationMessageFor(model => model.PestType)
</div>
Now it looks like it is working
现在看起来它正在工作
On the difference between DropDownList
and DropDownListFor
I have found useful infromation on this post
关于DropDownList
和DropDownListFor
我之间的区别,我在这篇文章中找到了有用的信息
回答by Gone Coding
You can fix the original problem quite simply with this in your GET
Create method:
您可以在GET
Create 方法中非常简单地解决原始问题:
ViewBag.PestType = new SelectList(Enum.GetValues(typeof(PestType)).OfType<PestType>());
and this in your POST Create method (where validation fails and it returns the view):
这在您的 POST Create 方法中(验证失败并返回视图):
ViewBag.PestType = new SelectList(Enum.GetValues(typeof(PestType)).OfType<PestType>(),
singlepest.PestType);
if you want to keep it strongly typed in the view use:
如果要在视图中保持强类型,请使用:
@Html.DropDownListFor(model => model.PestType, ViewBag.PestType as SelectList)
If you don't mind the weak typed version use the simpler:
如果您不介意弱类型版本,请使用更简单的:
@Html.DropDownList("PestType")
In either case I suggest you create all lists in the controller and not in the view.
无论哪种情况,我都建议您在控制器中而不是在视图中创建所有列表。
Explanation:
解释:
Basically DropDownlist
will search the ViewData
(i.e. your ViewBag
settings) for a list of options for the member of the same name (if a list is not explicitly provided).
基本上DropDownlist
会在ViewData
(即您的ViewBag
设置)中搜索同名成员的选项列表(如果未明确提供列表)。
I mocked up the whole project (MVC5/VS2013) and more of the code is below for your reference.
我模拟了整个项目(MVC5/VS2013),下面有更多代码供您参考。
Controller:
控制器:
using PestTypeTest.Models;
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Web;
using System.Web.Mvc;
namespace PestTypeTest.Controllers
{
public class PestTypeController : Controller
{
//
// GET: /PestType/
public ActionResult Index()
{
return RedirectToAction("Create");
}
public ActionResult Create()
{
ViewBag.PestType = new SelectList(Enum.GetValues(typeof(PestType)).OfType<PestType>());
return View();
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create(//(SinglePest singlepest)
[Bind(Include = "Alias, TechName, SerialNumber, PestType, Markings")] SinglePest singlepest)
{
try
{
if (ModelState.IsValid)
{
//db.SinglePests.Add(singlepest);
//db.SaveChanges();
return RedirectToAction("Index");
}
}
catch (DataException /* dex */)
{
ModelState.AddModelError("", "Unable to save changes, try again, if problem persits contact your administrator");
}
//ViewBag.SerialNumber = new SelectList(db.Sources, "SerialNumber", "SerialNumber", singlepest.SerialNumber);
ViewBag.PestType = new SelectList(Enum.GetValues(typeof(PestType)).OfType<PestType>(), singlepest.PestType);
return View(singlepest);
}
}
}
Views\PestType\Create.cshtml
视图\PestType\Create.cshtml
@model PestTypeTest.Models.SinglePest
@{
ViewBag.Title = "Create";
}
<h2>Create</h2>
@using (Html.BeginForm())
{
@Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>SinglePest</h4>
<hr />
@Html.ValidationSummary(true)
<div class="form-group">
@Html.LabelFor(model => model.PestType, new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.DropDownList("PestType")
@Html.ValidationMessageFor(model => model.PestType)
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.Alias, new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.Alias)
@Html.ValidationMessageFor(model => model.Alias)
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.TechName, new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.TechName)
@Html.ValidationMessageFor(model => model.TechName)
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.Markings, new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.Markings)
@Html.ValidationMessageFor(model => model.Markings)
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.SerialNumber, new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.SerialNumber)
@Html.ValidationMessageFor(model => model.SerialNumber)
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Create" class="btn btn-default" />
</div>
</div>
</div>
}
<div>
@Html.ActionLink("Back to List", "Index")
</div>
@section Scripts {
@Scripts.Render("~/bundles/jqueryval")
}