没有类型为“IEnumerable”的 ViewData 项具有键“PestType”
本文关键字:ViewData PestType SelectListItem 类型 IEnumerable | 更新日期: 2023-09-27 18:31:07
我正在学习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; }
}
这是害虫类型:
public enum PestType
{
Dog,
Cat,
Fox,
Rabbit,
Rat
}
这是控制器:
[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);
}
这是我收到错误的视图(没有类型为"IEnumerable"的视图数据项具有键"PestType"):
<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>
现在我看到了一些关于显示枚举的帖子,但我无法找到解决我的问题的方法。有人可以给我一些关于如何解决它的建议吗?
谢谢你的时间!
你有@Html.DropDownList("PestType", String.Empty)
,但第二个参数需要是一个IEnumerable<T>
。 您将需要模型中的害虫列表,然后使用model.Pests
例如,其中宠物是IEnumerable
。
编辑:基于评论...
但我想只展示各种类型的害虫(狗、猫等) 不是我数据库中的所有害虫
好的,这些是分类的,你能写一些类似的东西(手写所以检查语法)..
var pests = (from _context.Pests.Where(p => p.CategoryId == 1) select p.PestName).ToList();
如果您需要为枚举获取 IEnumerable(因为我不确定数据库是什么样子的),您可以使用...
Enum.GetValues(typeof(PestType))
.OfType<PestType>()
.Where(p => p == ??);
目前,您的模型仅包含一个存储值的位置,而不是用于填充下拉列表的数组/IEnumerable。
首先向模型添加一个 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; }
}
在控制器中:
public ActionResult Create()
{
var model = new SinglePest();
model.Pests = Enum.GetValues(typeof(PestType)).Cast<PestType>()
return View(model);
}
以及您的观点:
@Html.DropDownListFor(m => m.PestType, Model.Pests);
抱歉,如果我从记忆中写了这个有任何错误......
我在 DropDownList 上找到了这篇文章对于枚举似乎它正在解决我的问题。
所以我刚刚用这段新代码改变了视图:
<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>
现在看起来它正在工作
关于DropDownList
和DropDownListFor
之间的区别,我在这篇文章中找到了有用的信息
您可以在 GET
Create 方法中非常简单地解决原始问题:
ViewBag.PestType = new SelectList(Enum.GetValues(typeof(PestType)).OfType<PestType>());
这在你的 POST 创建方法中(验证失败并返回视图):
ViewBag.PestType = new SelectList(Enum.GetValues(typeof(PestType)).OfType<PestType>(),
singlepest.PestType);
如果要在视图中保持强类型,请使用:
@Html.DropDownListFor(model => model.PestType, ViewBag.PestType as SelectList)
如果您不介意弱类型版本,请使用更简单的版本:
@Html.DropDownList("PestType")
无论哪种情况,我都建议您在控制器中创建所有列表,而不是在视图中创建。
解释:
基本上,DropDownlist
将在ViewData
(即您的ViewBag
设置)中搜索同名成员的选项列表(如果未明确提供列表)。
我模拟了整个项目(MVC5/VS2013),下面有更多代码供您参考。
控制器:
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
@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")
}