首页 文章

从Enum创建的MVC Razor DropDownList

提问于
浏览
0

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

以下是我的模型:

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

2 回答

  • 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
    }
    
  • 0

    所以在真正停下来思考错误后我已经解决了我的问题 . 那么实际上有两个我会解释 .

    我收到的错误是:

    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动态字段与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>
    

相关问题