【问题标题】:ASP.NET MVC - Html.DropDownList - Value not set via ViewData.ModelASP.NET MVC - Html.DropDownList - 值未通过 ViewData.Model 设置
【发布时间】:2008-12-23 21:09:18
【问题描述】:

刚开始使用 ASP.NET MVC 并偶然发现了以下情况。感觉很像一个错误,但如果不是,我们将不胜感激:)

视图包含非常基本的东西

<%=Html.DropDownList("MyList", ViewData["MyListItems"] as SelectList)%>
<%=Html.TextBox("MyTextBox")%>

不使用模型时,按预期设置值和选定项:

//works fine
public ActionResult MyAction(){
  ViewData["MyListItems"] = new SelectList(items, "Value", "Text"); //items is an ienumerable of {Value="XXX", Text="YYY"}

  ViewData["MyList"] = "XXX"; //set the selected item to be the one with value 'XXX'
  ViewData["MyTextBox"] = "ABC"; //sets textbox value to 'ABC'

  return View();
}

但是当尝试通过模型加载时,文本框的值按预期设置,但下拉菜单没有获得选定的项目集。

//doesnt work
public ActionResult MyAction(){
  ViewData["MyListItems"] = new SelectList(items, "Value", "Text"); //items is an ienumerable of {Value="XXX", Text="YYY"}

  var model = new {
    MyList = "XXX", //set the selected item to be the one with value 'XXX'
    MyTextBox = "ABC" //sets textbox value to 'ABC'
  }

  return View(model);
}

有什么想法吗?我目前对此的想法是,也许在使用模型时,我们仅限于在 SelectList 构造函数上设置所选项目,而不是使用视图数据(工作正常)并将选择列表与模型一起传递——这将有好处稍微清理一下代码 - 我只是想知道为什么这种方法不起作用....

非常感谢您的任何建议

【问题讨论】:

    标签: asp.net-mvc html-helper


    【解决方案1】:

    实际上,您只需将 null 传递给 Html.DropDownList()
    我遇到了同样的问题,并使用反射器查看了 MVC 源代码。

    System.Web.Mvc.Extensions.SelectExtensions类的SelectInternal()方法中,检查selectList参数是否为null。 如果传入null,则正确查找SelectList

    这里是“代码隐藏”。

    ViewData["MyDropDown"] = new SelectList(selectListItems,
                                 "Value",
                                 "Text",
                                 selectedValue.ToString()
                             );
    

    这是 HTML 视图代码。

    <%= Html.DropDownList("MyDropDown", null,
            "** Please Select **",
            new { @class = "my-select-css-class" }
        ) %>
    

    注意:我使用的是 ASP.NET MVC 2.0(测试版)。

    更新说明:2012 年 1 月 31 日

    在过去 3 年广泛使用 ASP.NET MVC 之后,我更喜欢使用 Html.EditorFor() method 中的 additionalViewData

    将您的 [List Items] 作为 anonymous 对象传递到 Html.EditorFor() 方法中,并具有 与模型的属性相同的属性名称

    <%= Html.EditorFor(
        m => m.MyPropertyName,
        new { MyPropertyName = Model.ListItemsForMyPropertyName }
    ) %>
    

    如需了解更多详情,请参考my answer in another thread here

    【讨论】:

    • 谢谢...这是我见过的强类型视图问题的最佳解决方案...它适用于具有与下拉名称匹配的属性名称的模型,因此它应该...谢谢
    • 我同意。 “重命名你的领域”的口头禅会预先杀死模型与对象的绑定。这对我来说也是最好的解决方案。
    • 我认为如果属性是数组的一部分,这会中断
    【解决方案2】:

    经过一堆折边和处理后,它归结为以下代码行

    if (ViewData.ModelState.TryGetValue(key, out modelState))
    

    这意味着 MVC 试图通过仅查看 ViewData Dictionary 对象而不是向下遍历 ViewData.Model 对象来解析该值。

    我不确定这是错误、限制还是设计决定。但是,您可以通过以下方式修复它:

    <%= Html.TextBox("MyTextBox", ViewData.Model.MyTextBox) %>
    

    【讨论】:

    • 感谢托德的建议,正如我在帖子中提到的,如果使用模型,您可以通过以下方式解决它: var model{ MyList = new SelectList(items, "Value", "Text", selected_value) } 并且只是:
    • 它主要只是让我感到困惑的行为 - 至少你现在给了我一个开始 - 认为我需要弄清楚整个 ModelState 流程 - 如果它从那里出来,那么一定有从 ViewData 等加载内容的步骤
    • 嘿......这甚至不是一个答案......你怎么能拿起这个?您不能在 Html 扩展方法中设置选定的值,您必须在构建 ViewData 时在控制器中进行设置
    【解决方案3】:

    在创建 SelectList 集合时尝试在控制器操作中设置选定的值。

    ViewData["AddressTypeId"] = new SelectList(CustomerService.AddressType_List(), "AddressTypeId", "Name", myItem.AddressTypeId);

    【讨论】:

    • 这解决了我在尝试为下拉列表的项目选择值时的问题。谢谢!
    【解决方案4】:

    我显然来晚了。但我想添加此评论以防其他人遇到此问题。

    在MVC 2中。您可以执行以下操作来选择项目...

    public ActionResult Edit(int id)
            {
                Team team = _db.TeamSet.First(m => m.TeamID == id);
                var fanYear = from c in _db.FanYearSet select c;
                ViewData["FantasyYear"] = new SelectList(fanYear, "YearID", "FantasyYear", team.FanYearReference.EntityKey.EntityKeyValues[0].Value);
                var league = from c in _db.LeagueSet select c;
                ViewData["League"] = new SelectList(league, "LeagueID", "League_Name", team.LeaguesReference.EntityKey.EntityKeyValues[0].Value);
    
                return View(team);
            }
    

    第四个参数接受一个值,并将在下拉列表中选择您想要的值。在我的示例中,我有一个名为 team 的表,我将一个关系设置为一个名为 fanYear 和 League 的表。

    你可以看到我首先得到了我正在编辑的球队,然后建立了一个梦幻年的下拉列表和另一个联赛的下拉列表。为了确定球队的年份和联赛,我不得不使用实体参考。

    只是想把它放在那里。我找不到任何这样做的例子。

    【讨论】:

      【解决方案5】:

      当您遇到无效或 null ViewData 的问题时,请注意控制器的操作。

      假设您有一个名为 MyList 的 ViewData 用于 Html.DropDownlist,名为 MyList。

      如果您致电ModelState.AddModelError("MyList","Please select the profession"),您将使用此警告文本替换您的 ViewData 列表内容。

      这也是互联网上的人们在 DropDownList 上的 ViewData 遇到空问题的原因。

      最重要的是,请注意您在错误模型上的 ID,它们不得干扰您的 html 控件。

      【讨论】:

        【解决方案6】:

        我担心的是,您只能将列表用于一个字段。我有多个用户字段的实体,所以我使用以下内容:

        < %= Html.DropDownList("fieldAAA", 
                               new SelectList( (IEnumerable) ViewData["Users"], "Value", "Text", fieldAAA))
        
        %> 
        

        【讨论】:

          【解决方案7】:

          好吧,我可能会从这个线程中遗漏一些东西,但是在 C# 中,以下工作:

          Html.DropDownList("ProfessionGuid", (SelectList)ViewData["Professions"])
          

          其中 'ProfessionGuid' 是要在列表中选择的值。

          在 VB.Net 中,我相信它会是:

          Html.DropDownList("ProfessionGuid", ViewData["Professions"] AS SelectList)
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2016-04-17
            • 2014-11-09
            相关资源
            最近更新 更多