asp.net-mvc ASP.NET MVC - Html.DropDownList - 值未通过 ViewData.Model 设置

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/390083/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-07 23:14:09  来源:igfitidea点击:

ASP.NET MVC - Html.DropDownList - Value not set via ViewData.Model

asp.net-mvchtml-helper

提问by chrisb

Have just started playing with ASP.NET MVC and have stumbled over the following situation. It feels a lot like a bug but if its not, an explanation would be appreciated :)

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

The View contains pretty basic stuff

视图包含非常基本的东西

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

When not using a model, the value and selected item are set as expected:

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

//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();
}

But when trying to load via a model, the textbox has the value set as expected, but the dropdown doesnt get a selected item set.

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

//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);
}

Any ideas? My current thoughts on it are that perhaps when using a model, we're restricted to setting the selected item on the SelectList constructor instead of using the viewdata (which works fine) and passing the selectlist in with the model - which would have the benefit of cleaning the code up a little - I'm just wondering why this method doesnt work....

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

Many thanks for any suggestions

非常感谢您的任何建议

采纳答案by Todd Smith

After a bunch of hemming and hawing it boils down to the following line of code

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

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

which means MVC is trying to resolve the value by only looking at the ViewData Dictionary<> object and not traversing down into the ViewData.Model object.

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

Whether that's a bug, limitation or design decision I'm not sure. However, you can fix it the following way:

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

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

回答by stun

Actually, you just have to pass in nullfor the Html.DropDownList().
I was having the same exact problem, and used the Reflector to look at the MVC Source Code.

其实,你只需要传递nullHtml.DropDownList()
我遇到了同样的问题,并使用反射器查看 MVC 源代码。

In the System.Web.Mvc.Extensions.SelectExtensionsclass's SelectInternal()method, it checks whether the selectListparameter is nullor not. If it is passed in as null, it looks up the SelectListproperly.

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

Here is the "Code-behind".

这是“代码隐藏”。

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

Here is the HTML view code.

这是 HTML 视图代码。

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

Note: I'm using ASP.NET MVC 2.0 (Beta Version).

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

UPDATE NOTE: January 31st 2012

更新说明:2012 年 1 月 31 日

After extensively using ASP.NET MVC for the past 3 years, I prefer using additionalViewDatafrom the Html.EditorFor()methodmore.

在过去 3 年广泛使用 ASP.NET MVC 后,我更喜欢使用additionalViewDatafromHtml.EditorFor()方法

Pass in your [List Items]as an anonymousobject with the same property nameas the Model's property into the Html.EditorFor()method.

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

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

If you want more details, please refer to my answer in another thread here.

如果您想了解更多详细信息,请参阅我在另一个主题中的回答

回答by IamNotaRobot

try setting the selected value in the controller action when creating the SelectList collection.

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

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

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

回答by Michael

I'm obviously late here. But I wanted to add this comment incase someone else came across this issue.

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

In MVC 2. You can do the following to select the item...

在 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);
        }

The fourth parameter takes a value and will select the value you want in the dropdownlist. In my example I have a table called team and it is I have a relationship set to a table called fanYear and league.

第四个参数采用一个值,将在下拉列表中选择您想要的值。在我的示例中,我有一个名为 team 的表,它与名为 fanYear 和 League 的表建立了关系。

You can see that I first get the team that I'm editing, then building a dropdownlist of fantasy year and another for leagues. In order to determine the year and league for the team, I had to use Entity Reference.

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

Just wanted to put that out there. I couldn't find any examples of doing this.

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

回答by Junior Mayhé

When you have problems with invalid or null ViewData, pay attention to your controller's action.

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

Suppose you have a ViewData called MyList for Html.DropDownlist called MyList.

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

If you call ModelState.AddModelError("MyList","Please select the profession")you'll replace your ViewData list content with the this warning text.

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

That's also why people around internet is having null problems with ViewData on DropDownList.

这也是为什么互联网上的人们在 DropDownList 上的 ViewData 存在空问题的原因。

The bottom line is, pay attention to your IDs on error model, they must not interfere with your html controls.

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

回答by user448862

My concern with this is that you may only use the list for one field. I have Entities with multiple user fields, so I use the following:

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

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

%> 

回答by Aracnid

Ok I may be missing something from this thread however in C# the following works:

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

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

Where 'ProfessionGuid' is the value to be selected in the list.

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

In VB.Net I believe it would be:

在 VB.Net 我相信它会是:

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