Asp.net mvc 3 ViewBag多个SelectListItems

Asp.net mvc 3 ViewBag多个SelectListItems,asp.net-mvc-3,viewbag,dropdownlistfor,Asp.net Mvc 3,Viewbag,Dropdownlistfor,从我的MVC3应用程序中获得一些非常恼人的行为。我得到了一个有3个值的模型: [DisplayName("Airlines ")] [StringLength(2, ErrorMessage = "Airline codes can only be 2 characters in length")] public string AirlineCode1 { get; set; } [DisplayName("Airlines")] [StringLength(2, ErrorMessage =

从我的MVC3应用程序中获得一些非常恼人的行为。我得到了一个有3个值的模型:

[DisplayName("Airlines ")]
[StringLength(2, ErrorMessage = "Airline codes can only be 2 characters in length")]
public string AirlineCode1 { get; set; }

[DisplayName("Airlines")]
[StringLength(2, ErrorMessage = "Airline codes can only be 2 characters in length")]
public string AirlineCode2 { get; set; }

[DisplayName("Airlines")]
[StringLength(2, ErrorMessage = "Airline codes can only be 2 characters in length")]
public string AirlineCode3 { get; set; }
现在这些都是从一个
DropDowList
中填充的,因此我在
ViewBag
中弹出
DropDownListItem
并在视图中呈现它们,例如:

@Html.LabelFor(l => l.AirlineCode1) <span>(select/enter code in box on right)</span>
<div id="airportCode1">
    @Html.DropDownListFor(d => d.AirlineCode, ViewBag.AirLines as List<SelectListItem>) <input type="text" maxlength="2" value="@Model.AirlineCode1" />
</div>
<div id="airportCode2" style="@Model.AirlineCode2Style">
     @Html.DropDownListFor(d => d.AirlineCode, ViewBag.AirLines2 as List<SelectListItem>) <input type="text" maxlength="2" value="@Model.AirlineCode2" />
</div>
<div id="airportCode3">
    @Html.DropDownListFor(d => d.AirlineCode3, ViewBag.AirLines3 as List<SelectListItem>) <input type="text" maxlength="2" value="@Model.AirlineCode3" />
</div>
吊杆,固定。问题是
PopulateAirlines
是一个昂贵的过程

问题是ViewBag似乎正在维护3个
SelectListItem
列表之间的引用。我如何阻止它这样做,并且仍然只调用一次
PopulateAirlines(用户)

我尝试了下面的代码,结果完全失败了:

IEnumerable<SelectListItem> airLines = PopulateAirlines(user);
ViewBag.AirLines = airLines;
ViewBag.AirLines2 = airLines.Select(s => new SelectListItem() { Text = s.Text, Value = s.Value, Selected = s.Selected });
ViewBag.AirLines3 = airLines.Select(s => new SelectListItem() { Text = s.Text, Value = s.Value, Selected = s.Selected });
IEnumerable airLines=PopulateAirlines(用户);
ViewBag.AirLines=航空公司;
ViewBag.AirLines2=airLines.Select(s=>newselectListItem(){Text=s.Text,Value=s.Value,Selected=s.Selected});
ViewBag.AirLines3=airLines.Select(s=>newselectListItem(){Text=s.Text,Value=s.Value,Selected=s.Selected});
错误如下:

没有类型为“IEnumerable”的ViewData项 钥匙是“AirlineCode2”


什么

这可能是因为在该代码中:

IEnumerable<SelectListItem> airLines = PopulateAirlines(user);
ViewBag.AirLines = airLines;
ViewBag.AirLines2 = airLines;
ViewBag.AirLines3 = airLines;
IEnumerable airLines=PopulateAirlines(用户);
ViewBag.AirLines=航空公司;
ViewBag.AirLines2=航空公司;
ViewBag.AirLines3=航空公司;
所有
ViewBag
属性都指向同一列表。因此,对列表的更改将反映在引用任何属性时。调用
PopulateAirlines
()方法时,将创建3个不同的列表


您需要创建三个单独的列表,但只需使用
PopulateAirlines
方法创建第一个列表,然后克隆它两次。这不会那么昂贵。

扔掉ViewBag。它不是强类型的,而且传递数据的方式很难看。创建一个包含各种航空公司信息的ViewModel,问题解决了:)我从不同意这个观点。我不想收回这些数据,它只是填充下拉列表,所以使用ViewBag更有效,因为它可以防止列表在两个方向上序列化。对我来说,ViewBag是只读的,用于创建和忘记数据。不,它并不是真的更高效。它基本上可以忽略不计,仅仅因为它在一个视图模型中是一个方向并不意味着它必须在接收视图模型上,甚至不一定要在接收视图模型上。另一方面,您的实现很脆弱,容易出现重构错误,通过在html帮助程序中使用viewbag在幕后隐藏行为,并且除了最小的web应用程序外,一般建议不要在任何情况下使用这种方法。有些人甚至说永远不要使用它(我通常接受像页面标题这样的std使用)。请看Darin Dmitrov在这里的许多帖子,以获得一些好的参考。我已经听过好几次了,虽然我理解这一点,但对我来说,这听起来并不完全正确。我认为,通过将这些放在我的模型或ViewModel中,我所做的就是用一堆我不想放在里面的对象把它弄得乱七八糟。如果是数据,那是一回事,但这只是一种有效呈现下拉列表的机制!无论如何,我把它整理好了,但它确实涉及到重构我的PopulateAirlines方法。
IEnumerable<SelectListItem> airLines = PopulateAirlines(user);
ViewBag.AirLines = airLines;
ViewBag.AirLines2 = airLines.Select(s => new SelectListItem() { Text = s.Text, Value = s.Value, Selected = s.Selected });
ViewBag.AirLines3 = airLines.Select(s => new SelectListItem() { Text = s.Text, Value = s.Value, Selected = s.Selected });
IEnumerable<SelectListItem> airLines = PopulateAirlines(user);
ViewBag.AirLines = airLines;
ViewBag.AirLines2 = airLines;
ViewBag.AirLines3 = airLines;