2

我正在学习 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);
    }

这是我收到错误的视图(没有具有键“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>

现在我看到了一些关于显示枚举的帖子,但我无法找到解决我的问题的方法。请有人给我一些关于如何解决它的建议吗?

感谢您的时间!

4

4 回答 4

4

你有@Html.DropDownList("PestType", String.Empty),但第二个参数必须是IEnumerable<T>. 您将需要模型中的害虫列表,然后使用model.Pests例如其中 Pets 是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 == ??);
于 2013-09-13T08:51:26.693 回答
4

目前,您的模型仅包含一个存储值的位置,而不是用于填充下拉列表的 Array/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);

对不起,如果有任何错误我是从记忆中写出来的......

于 2013-09-13T08:59:55.473 回答
1

我在DropDownListFor enums上找到了这篇文章 ,看来它正在解决我的问题。

所以我刚刚用这段新代码改变了视图:

<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中找到了有用的信息

于 2013-09-13T09:07:10.950 回答
1

您可以在GETCreate 方法中非常简单地解决原始问题:

ViewBag.PestType = new SelectList(Enum.GetValues(typeof(PestType)).OfType<PestType>());

这在您的 POST Create 方法中(验证失败并返回视图):

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

视图\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")
}
于 2013-11-13T14:46:12.757 回答