从Enum创建的MVC Razor DropDownList

时间:2018-08-07 14:35:27

标签: asp.net-mvc drop-down-menu

我正在尝试创建一个过滤器下拉列表,以将其作为参数传递回我的控制器。我似乎无法显示下拉列表。

下面是我的模特:

using System;

namespace ShiftPatternConfigurator.Models
{
    public class ShiftModel
    {
        public int ShiftNo;
        public string ShiftName;
        public DateTime StartTime;
        public DateTime FinishTime;
        public string Team;
        public int Week;
        public int CycleWeek = 0;
        public string StartDay;
        public DateTime StartDate;
    }

    public enum Month
    {
        January = 1,
        February = 2,
        March = 3,
        April = 4,
        May = 5,
        June = 6,
        July = 7,
        August = 8,
        September = 9,
        October = 10,
        November = 11,
        December = 12
    }
}

这是我的控制器:

using Oracle.ManagedDataAccess.Client;
using ShiftPatternConfigurator.Models;
using System;
using System.Collections.Generic;
using System.Text;
using System.Web.Mvc;

namespace ShiftPatternConfigurator.Controllers
{
    public class HomeController : Controller
    {
        // list to hold the shift data
        List<ShiftModel> shiftData = new List<ShiftModel>();
        // GET: Index
        public ActionResult Index()
        {
            ViewBag.Title = "Shift Pattern Configurator";
            // create the select list to help pick which months shifts to look at
            ViewBag.Month = new SelectList(Enum.GetValues(typeof(Month)),"Month", "Month", DateTime.Now.ToString("MMMM"));
            // create the shift data to display in the page          
            return View(GetShiftData(shiftData, ViewBag.Month));
        }

        [HttpPost]
        public ActionResult SelectMonth(SelectList Month)
        {
            ViewBag.Title = "Shift Pattern Configurator";          
            ViewBag.Month = Month;
            return View(GetShiftData(shiftData, Month));
        }

        private List<ShiftModel> GetShiftData(List<ShiftModel> shiftData, SelectList monthIn)
        {
            // get the month enum from our selected value
            Month month = (Month)Enum.Parse(typeof(Month), monthIn.SelectedValue.ToString());
            DateTime start;
            DateTime finish;
            // if its the end of the year (December) 
            if ((int)month == 12)
            {
                // then show december and january
                start = new DateTime(DateTime.Today.Year, (int)month, 1, 0, 0, 0);
                finish = new DateTime(DateTime.Today.Year + 1, 2, 1, 0, 0, 0);
            }
            else
            {
                start = new DateTime(DateTime.Today.Year, (int)month, 1, 0, 0, 0);
                finish = new DateTime(DateTime.Today.Year, (int)month + 1, 1, 0, 0, 0);
            }

            // build the query (Get shift records that are greater than or equal to today and 2 weeks worth)
            StringBuilder oracleQuery = new StringBuilder("SELECT SHIFT_NO, SHIFT_NAME, START_TIME, FINISH_TIME, TEAM, WEEK, CYCLE_WEEK, START_DAY, START_DATE ");
            oracleQuery.Append("FROM PROD_KPI.NEW_SHIFTS ");
            oracleQuery.Append("WHERE START_DATE BETWEEN :pSTART_DATE AND :pEND_DATE ");
            oracleQuery.Append("ORDER BY START_DATE DESC ");

            // connection to oracle
            string connectionString = System.Configuration.ConfigurationManager.ConnectionStrings["IFSOracleConnection"].ConnectionString;
            OracleConnection conn = new OracleConnection(connectionString);
            conn.Open();

            // oracle command object and parameters
            OracleCommand cmd = new OracleCommand(oracleQuery.ToString(), conn);
            cmd.Parameters.Add(new OracleParameter("pSTART_DATE", OracleDbType.Date));
            cmd.Parameters[0].Value = start;
            cmd.Parameters.Add(new OracleParameter("pEND_DATE", OracleDbType.Date));
            cmd.Parameters[1].Value = finish;

            // execute the query
            OracleDataReader reader = cmd.ExecuteReader();
            while (reader.Read())
            {
                //object o = reader.IsDBNull(0) ? null : reader.GetValue(0);
                ShiftModel shiftRecord = new ShiftModel
                {
                    ShiftNo = reader.GetInt32(reader.GetOrdinal("SHIFT_NO")),
                    ShiftName = reader.IsDBNull(reader.GetOrdinal("SHIFT_NAME")) ? null : reader.GetString(reader.GetOrdinal("SHIFT_NAME")),
                    StartTime = reader.GetDateTime(reader.GetOrdinal("START_TIME")),
                    FinishTime = reader.GetDateTime(reader.GetOrdinal("FINISH_TIME")),
                    Team = reader.IsDBNull(reader.GetOrdinal("TEAM")) ? null : reader.GetString(reader.GetOrdinal("TEAM")),
                    Week = reader.GetInt32(reader.GetOrdinal("WEEK")),
                    CycleWeek = reader.GetInt32(reader.GetOrdinal("CYCLE_WEEK")),
                    StartDay = reader.IsDBNull(reader.GetOrdinal("START_DAY")) ? null : reader.GetString(reader.GetOrdinal("START_DAY")),
                    StartDate = reader.GetDateTime(reader.GetOrdinal("START_DATE"))
                };
                shiftData.Add(shiftRecord);
            }

            reader.Close();

            return shiftData;
        }
    }
}

这是我的剃刀视图:

@using ShiftPatternConfigurator.Models
@model IEnumerable<ShiftPatternConfigurator.Models.ShiftModel>

<h2>@ViewBag.Title</h2>

@using (Html.BeginForm("SelectMonth", "HomeController", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
    @Html.DropDownList("Month", (SelectList)ViewBag.Month)
    <input type="submit" value="SelectMonth" />
}


<table class="table">
    <tr>
        <th>Shift No</th>
        <th>Shift Name</th>
        <th>Start Time</th>
        <th>Finish Time</th>
        <th>Team</th>
        <th>Week</th>
        <th>Start Day</th>
        <th>Start Date</th>
        <th></th>
    </tr>

    @if (Model.Count() > 0)
    {
        foreach (var item in Model)
        {
            <tr>
                <td>@item.ShiftNo</td>
                <td>@item.ShiftName</td>
                <td>@item.StartTime</td>
                <td>@item.FinishTime</td>
                <td>@item.Team</td>
                <td>@item.Week</td>
                <td>@item.StartDay</td>
                <td>@item.StartDate.ToShortDateString()</td>
                <td>
                    @Html.ActionLink("Edit", "Edit", new { /* id=item.PrimaryKey */ }) |
                    @Html.ActionLink("Details", "Details", new { /* id=item.PrimaryKey */ }) |
                    @Html.ActionLink("Delete", "Delete", new { /* id=item.PrimaryKey */ })
                </td>
            </tr>
        }
    }
    else
    {
        <tr>
            <td colspan="10" align="center"><h2>No Data</h2></td>
        </tr>
    }

</table>

有人可以建议如何创建DropDownList对象,以便在提交表单时将Month参数传递回HomeController中我选择的月份ActionResult。

当我运行代码并在创建DropDownList之前中断时,如果检查ViewBag.Month,我可以看到一个填充的SelectList,其Selected Value设置为当月。

请咨询

编辑:我收到的错误如下:

System.Web.HttpException:'数据绑定:'ShiftPatternConfigurator.Models.Month'不包含名称为'Month'的属性。

2 个答案:

答案 0 :(得分:1)

您可以在答案显示时手动构建选择列表,也可以使用内置的HTML帮助器$,它将以更少的代码实现我所希望的。用法示例如下:

Html.EnumDropDownListFor

,您的视图(public class MyViewModel { //Month is an enum here public Month Month { get; set; } } )如下所示:

MonthExample.cshtml

该框架将看到Month是一个枚举,并自动为下拉列表构建选项,而不是您手动执行。

如果您想查看控制器get / post的简单示例,它们可能如下所示:

@model MyProject.MyViewModel
...
@using(Html.BeginForm("MonthExample", "ControllerName", FormMethod.Post))
{
    @Html.EnumDropDownListFor(x => x.Month)
    <button type="submit">Save</button>
}

...

答案 1 :(得分:0)

因此,在真正停止思考错误之后,我已修复了我的问题。 好吧,实际上有两个我会解释。

我收到的错误是:

System.Web.HttpException:'数据绑定:'ShiftPatternConfigurator.Models.Month'不包含名称为'Month'的属性。

这使我想到一个事实,因为我的枚举是枚举,所以没有dataValueField或dataTypeField。

所以我看了我在创建SelectList的代码:

ViewBag.Month = new SelectList(Enum.GetValues(typeof(Month)), "Month", "Month", DateTime.Now.ToString("MMMM"));

我仔细研究了重载的方法,发现其中一个不需要dataValueField或dataTypeField,因此我将代码修改为以下内容:

ViewBag.Month = new SelectList(Enum.GetValues(typeof(Month)), DateTime.Now.ToString("MMMM"));

然后,这允许渲染DropDownList。但是,我仍然遇到未设置“选定值”的问题。快速浏览Google之后,我发现您不能将ViewBags动态字段设置为与models属性相同。

所以我这样修改了控制器代码:

ViewBag.MonthFilter = new SelectList(Enum.GetValues(typeof(Month)), DateTime.Now.ToString("MMMM"));

和我的查看代码如下:

@using (Html.BeginForm("SelectMonth", "HomeController", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
    @Html.DropDownList("Month", (SelectList)ViewBag.MonthFilter)
    <input type="submit" value="SelectMonth" />
}

编辑:这是使用@GregH提供的答案后我的新更新代码

型号:

using System;
using System.Collections.Generic;

namespace ShiftPatternConfigurator.Models
{
    // view model
    public class ShiftViewModel
    {
        public IEnumerable<ShiftModel> Shifts { get; set; }
        public Month Month { get; set; }
    }

    // shift model
    public class ShiftModel
    {
        public int ShiftNo;
        public string ShiftName;
        public DateTime StartTime;
        public DateTime FinishTime;
        public string Team;
        public int Week;
        public int CycleWeek = 0;
        public string StartDay;
        public DateTime StartDate;
    }

    // month enum
    public enum Month
    {
        January = 1,
        February = 2,
        March = 3,
        April = 4,
        May = 5,
        June = 6,
        July = 7,
        August = 8,
        September = 9,
        October = 10,
        November = 11,
        December = 12
    }
}

控制器:

using Oracle.ManagedDataAccess.Client;
using ShiftPatternConfigurator.Models;
using System;
using System.Collections.Generic;
using System.Text;
using System.Web.Mvc;

namespace ShiftPatternConfigurator.Controllers
{
    public class HomeController : Controller
    {
        // GET: Index
        public ActionResult Index()
        {
            ViewBag.Title = "Shift Pattern Configurator Test";
            ShiftViewModel view = new ShiftViewModel
            {
                Month = new Month()
            };
            view.Month = (Month)DateTime.Now.Month;
            view.Shifts = GetShiftData(view.Month);       
            return View(view);
        }

        [HttpPost]
        public ActionResult Index(ShiftViewModel view)
        {
            ViewBag.Title = "Shift Pattern Configurator";
            view.Shifts = GetShiftData(view.Month);
            return View(view);
        }

        private List<ShiftModel> GetShiftData(Month month)...
    }
}

查看:

@model ShiftPatternConfigurator.Models.ShiftViewModel

<h2>@ViewBag.Title</h2>

@using (Html.BeginForm("Index", "Home", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
    @Html.EnumDropDownListFor(x => x.Month)
    <input type="submit" value="SelectMonth" />
}
<table class="table">
    <tr>
        <th>Shift No</th>
        <th>Shift Name</th>
        <th>Start Time</th>
        <th>Finish Time</th>
        <th>Team</th>
        <th>Week</th>
        <th>Start Day</th>
        <th>Start Date</th>
        <th></th>
    </tr>

    @if (Model.Shifts.Count() > 0)
    {
        foreach (var item in Model.Shifts)
        {
            <tr>
                <td>@item.ShiftNo</td>
                <td>@item.ShiftName</td>
                <td>@item.StartTime</td>
                <td>@item.FinishTime</td>
                <td>@item.Team</td>
                <td>@item.Week</td>
                <td>@item.StartDay</td>
                <td>@item.StartDate.ToShortDateString()</td>
                <td>
                    @Html.ActionLink("Edit", "Edit", new { /* id=item.PrimaryKey */ }) |
                    @Html.ActionLink("Details", "Details", new { /* id=item.PrimaryKey */ }) |
                    @Html.ActionLink("Delete", "Delete", new { /* id=item.PrimaryKey */ })
                </td>
            </tr>
        }
    }
    else
    {
        <tr>
            <td colspan="10" align="center"><h2>No Data</h2></td>
        </tr>
    }

</table>