代码之家  ›  专栏  ›  技术社区  ›  Comic Coder

从枚举创建的MVC Razor DropDownList

  •  0
  • Comic Coder  · 技术社区  · 8 年前

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

    以下是我的模型:

    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中的Select Month ActionResult。

    当我在创建DropDownList之前运行我的代码并中断时,如果我检查我的viewBag.month,我可以看到一个填充的selectlist,其中选定的值设置为当前月份。

    请给我建议。

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

    System.Web.httpException:“DataBinding:”ShiftPatternConfigurator.Models.Month“不包含名为“Month”的属性。”

    2 回复  |  直到 7 年前
        1
  •  1
  •   GregH    7 年前

    您可以在回答显示时手动构建选择列表,也可以使用内置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>
    }
    
    ...
    

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

    如果您希望看到控制器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
    }
    
        2
  •  0
  •   Comic Coder    7 年前

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

    我收到的错误是:

    System.Web.httpException:“DataBinding:”ShiftPatternConfigurator.Models.Month“不包含名为“Month”的属性。”

    这让我想到一个事实,我的枚举没有DataValueField或DataField,因为它是一个枚举。

    因此,我查看了创建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。但是,我仍然遇到了一个未设置所选值的问题。在快速搜索之后,我发现你不能将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>