ASP.NET MVC - Html.DropDownList - 未通过ViewData.Model设置的值

时间:2008-12-23 21:09:19

标签: asp.net-mvc html-helper

刚刚开始使用ASP.NET MVC并且遇到了以下情况。感觉很像一个bug,但如果不是,可以理解一下解释:)

视图包含非常基本的东西

<%=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构造函数上设置所选项而不是使用viewdata(工作正常)并将选择列表与模型一起传递 - 这将带来好处清理代码有点 - 我只是想知道为什么这种方法不起作用....

非常感谢任何建议

7 个答案:

答案 0 :(得分:23)

实际上,您只需要为null传递 Html.DropDownList()
我遇到了同样的问题,并使用Reflector来查看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

[列表项] 作为anonymous对象,将相同的属性名称作为Model的属性传递到Html.EditorFor()方法。

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

如果您想了解更多详情,请参阅my answer in another thread here

答案 1 :(得分:5)

经过一堆折边和唠叨之后,它归结为以下代码行

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

这意味着MVC只是通过查看ViewData Dictionary&lt;&gt;来尝试解析该值。对象而不是遍历到ViewData.Model对象。

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

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

答案 2 :(得分:2)

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

ViewData [“AddressTypeId”] =新的SelectList(CustomerService.AddressType_List(),“AddressTypeId”,“Name”, myItem.AddressTypeId );

答案 3 :(得分:2)

我显然已经迟到了。但我想添加此评论,以防其他人遇到此问题。

在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的表。

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

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

答案 4 :(得分:-1)

好的,我可能会遗漏这个帖子的内容,但是在C#中有以下作品:

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

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

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

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

答案 5 :(得分:-1)

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

假设您有一个名为MyList for Html.DropDownlist的ViewData名为MyList。

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

这也是为什么互联网上的人在DropDownList上使用ViewData时出现零问题的原因。

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

答案 6 :(得分:-1)

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

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

%>