【问题标题】:MVC Razor DropDownList created from Enum从 Enum 创建的 MVC Razor DropDownList
【发布时间】:2019-01-14 16:45:17
【问题描述】:

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

下面是我的模型:

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

这是我的 Razor 视图:

@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: 'DataBinding: 'ShiftPatternConfigurator.Models.Month' 不包含名为“Month”的属性。'

【问题讨论】:

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


    【解决方案1】:

    您可以在答案显示时手动构建选择列表,也可以使用内置的 Html 帮助程序Html.EnumDropDownListFor,这将实现我相信您正在寻找的代码更少。用法示例如下:

    public class MyViewModel
    {
        //Month is an enum here
        public Month Month { get; set; }
    }
    

    您的视图 (MonthExample.cshtml) 看起来像:

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

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

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

    public ActionResult MonthExample()
    {
        return View(new MyViewModel());
    }
    
    [HttpPost]
    public ActionResult MonthExample(MyViewModel model)
    {
        //here model.Month will have the selected month from the dropdown list
    }
    

    【讨论】:

    • 这是最好的答案。我修改了我的代码以使用上面的@GregH。我将在下面发布新的更新代码。我修改了我的模型以使用 ViewModel,我可以在其中构建控制器代码中所需的项目以显示在我的视图中。
    【解决方案2】:

    所以在真正停下来思考错误之后,我已经解决了我的问题。 其实有两个我会解释。

    我收到的错误是:

    System.Web.HttpException: 'DataBinding: '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。但是,我仍然遇到未设置 Selected 值的问题。快速谷歌后,我发现您无法将 ViewBags 动态字段设置为与模型属性相同。

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

    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>
    

    【讨论】:

    • 还有一个 html 助手 Html.EnumDropdownListFor(...) 可以为您简化此操作
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-07-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多