【问题标题】:How to add static list of items in MVC Html.DropDownList()如何在 MVC Html.DropDownList() 中添加静态项目列表
【发布时间】:2009-05-15 05:41:03
【问题描述】:

我想在 ASP.NET MVC 中将 SelectList() 中的静态项目列表分配给 Html.DropDownList(),最佳做法是什么?

我正要尝试找到一种使用new SelectList(new {key = "value"}... 的方法,但是一个,它不起作用,第二,我是否会在这里违反法律,我的静态列表是否应该在ViewData 中声明并通过作为IList/IENumerable?

【问题讨论】:

    标签: c# .net asp.net asp.net-mvc html-helper


    【解决方案1】:

    最好不要在视图中创建 SelectList。您应该在控制器中创建它并使用 ViewData 传递它。

    例子:

      var list = new SelectList(new []
                                              {
                                                  new {ID="1",Name="name1"},
                                                  new{ID="2",Name="name2"},
                                                  new{ID="3",Name="name3"},
                                              },
                                "ID","Name",1);
                ViewData["list"]=list;
                return View();
    

    您传递给构造函数:IEnumerable 对象、值字段、文本字段和选定值。

    在视图中:

     <%=Html.DropDownList("list",ViewData["list"] as SelectList) %>
    

    【讨论】:

    • 同意马尔万的观点。创建一个 SelectList 对象并将其传递给您的视图。就个人而言,我会有强类型视图,但这超出了这个问题的范围。
    • 我用的是强类型视图,为什么要在视图中定义SelectList?这是“特定视图”的事情吗?我认为简单地公开数据会更好,这就是你要给出一个视图,数据而不是上下文和数据。?
    • 其实我认为这是非常错误的,SelectList 用于呈现完全特定于 UI 的下拉列表。如果我现在想将此数据用于复选框列表或不支持 SelectList 的东西怎么办?
    • 我认为最好在控制器中定义您的 SelectList 以保持您的视图干净并包含尽可能少的代码。如果您检查 Nerd Dinner 应用程序,您会看到它做了同样的事情。
    • OK Marwan,我仍然想检查一下。但是,我想确保我不只是偏爱清洁而不是正确。
    【解决方案2】:

    所有 MVC 新手最初都避免使用“M”这个词,但它确实从 MVC 首字母缩写词的开头开始。所以也许,只是也许,你可能想从一个模型开始你的解决方案......只是说。

    不要重复自己 (DRY)。您将最终将“new PageData()”复制并粘贴到将选项列表传递给视图的每个控制器。然后你会想要删除或添加一个选项,并且必须编辑每个控制器的 PageData。

    此外,您希望以最少的不必要冗长的“add”、“new”、“IS”和“Name”键入最少的代码。因为您在选择选项(和/或单选按钮列表)中只有一个键值对,所以请使用尽可能轻的数据结构,即模型中的 Dictionary --。

    然后只需在 Controller 中引用 Model,并使用包含 LINQ Lambda 表达式的 DropDownListFor 将 Dictionary 转换为 View 中的 SelectList。

    被吓到了?你不是一个人。我当然是。这是我用来自学 M、V 和 C 的示例:

    MVC 的模型部分:

    using System.Web.Security;
    using System.Collections.Generic;
    using System.Text;
    using System.Linq.Expressions;
    using System.Web.Routing;
    using System.Web.Helpers;
    using System.Web.Mvc.Html;
    using MvcHtmlHelpers;
    using System.Linq;
    
    // EzPL8.com is the company I work for, hence the namespace root. 
        // EzPL8 increases the brainwidths of waiters and bartenders by augmenting their "memories" with the identifies of customers by name and their food and drink preferences.
       // This is pedagogical example of generating a select option display for a customer's egg preference.  
    
    namespace EzPL8.Models     
    {
        public class MyEggs    
        {
            public Dictionary<int, string> Egg { get; set; }
    
            public MyEggs()  //constructor
            {
                Egg = new Dictionary<int, string>()
                {
                    { 0, "No Preference"},  //show the complete egg menu to customers
                    { 1, "I hate eggs"},    //Either offer an alternative to eggs or don't show eggs on a customer's personalized dynamically generated menu
    
                    //confirm with the customer if they want their eggs cooked their usual preferred way, i.e.
                    { 2, "Over Easy"},  
                    { 3, "Sunny Side Up"},
                    { 4, "Scrambled"},
                    { 5, "Hard Boiled"},
                    { 6, "Eggs Benedict"}
                };
        }
    }
    

    Controller 现在相当简单,只需传递模型。它避免了创建一个孤立的概念,这可能不孤立于一页。:

    public ActionResult Index()
    {
       var model = new EzPL8.Models.MyEggs();
       return View(model);
    }
    

    视图使用DropDownListFor(而不是DropDownList),并且需要在事件重构中使用强类型的Lambda表达式:

    @Html.DropDownListFor(m => m.Egg, new SelectList( Model.Egg, "Key", "Value"))
    

    瞧,生成的 HTML:

    <select id="Egg" name="Egg">
    <option value="0">No Preference</option>
    <option value="1">I hate eggs</option>
    <option value="2">Over Easy</option>
    <option value="3">Sunny Side Up</option>
    <option value="4">Scrambled</option>
    <option value="5">Hard Boiled</option>
    <option value="6">Eggs Benedict</option>
    </select>
    

    注意:不要被 &lt;option value="6"&gt; 中的 VALUE 混淆,它是字典中的键,来自 SelectList() 中的“Value”,它是结束的文本/标题(例如 Eggs Benedict)在选项标签之间。

    用例: 为了最大限度地减少应用程序和数据库之间的流量,我创建了一个静态列表,以避免数据库查询下拉列表,如果有的话也很少更改。然而,变化是不可避免的,从现在起六个月后,我客户餐厅的一名用餐者去世了;不是因为绿色的火腿,而是因为他们对鸡蛋过敏,厨师在他们的华夫饼里混了一些。

    餐厅需要立即更新其客户信息,以包括食物过敏。虽然他们喜欢回头客,但他们对死去的客户作为僵尸回来并不酷,因为他们的信用卡被取消,他们无法付款。

    反问:我应该修改所有与客户鸡蛋偏好相关的控制器和视图吗?或者只是将 { 7, "Allergic to Eggs"} 插入模型中?

    另一个反问:煎蛋不是鸡蛋吗?是否要将 {8, "Omelette, Western"}, {9, "Omelette, Mushroom-Feta-Spinach"} 添加到模型中,并让新添加的内容自动传播到所有使用它们的视图中的所有下拉列表中?

    底线这可能比您要求的要多,...但您确实说的是 MVC,而不仅仅是 VC:
    1. 在 *M*VC 中使用模型。 2. Use a dictionary in the Model when a select list is based on nothing more than a "primary key" and a title. 3. 如果您的静态列表与某处的数据库查找表不匹配,则您的应用程序可能不是很有用。当您向静态列表添加选项时,您很可能还需要对查找表执行插入操作,以避免与数据库中的其他表发生主键/外键关系完整性错误。 4. 使用 lambda 和强类型数据结构来避免错误并获得 typeahead 支持。

    【讨论】:

    • 所有EzPL8 引用是怎么回事?我迷路了……还是我错过了这个笑话?
    • -1 用于 EzPL8 故事。 +1 用于从模型中提取数据。
    【解决方案3】:

    好的,我决定接受自己的建议,这应该在控制器中定义:

    仅供参考,我刚回来:

    PageData data = new PageData()
               {
                   Formats = new[]
                                 {
                                     new { ID = "string", Name = "Text" },
                                     new { ID = "int", Name = "Numeric" },
                                     new { ID = "decimal", Name = "Decimal" },
                                     new { ID = "datetime", Name = "Date/Time" },
                                     new { ID = "timespan", Name = "Stopwatch" }
                                 },
                   .............
    
               };
    return View(data);
    

    ...(忽略上下文)并在 View ASPX 端:

    <%= Html.DropDownList("type.field", new SelectList(ViewData.Model.Formats, "ID", "Name"...
    

    如果有人有更优化的方法,我很乐意接受他们的回答。

    【讨论】:

    • 我选择了我的答案,因为它是我选择的答案。
    • 这工作正常,但如果我想下拉加载 Decimal 作为启动值,我该怎么办?
    • 在控制器中定义它比在视图中更好,但正如@JulesBartow 所建议的那样,它确实应该在模型中。如果您想在其他地方重用下拉菜单怎么办?剪切和粘贴不是正确的答案。
    猜你喜欢
    • 1970-01-01
    • 2022-06-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-31
    • 2022-11-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多