ViewBag多个SelectListItems

时间:2013-01-02 16:25:40

标签: 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 = "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填充的,所以我弹出DropDownListItem中的ViewBag并在视图中呈现它们:

@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>

所以我的控制器看起来像:

IEnumerable<SelectListItem> airLines = PopulateAirlines(user);
ViewBag.AirLines = airLines;
ViewBag.AirLines2 = airLines;
ViewBag.AirLines3 = airLines;

现在在某些情况下,我想在模型中预先AirLineCode 。所以我在控制器中设置了模型值。这导致了一些奇怪的行为。突然,我的所有DropDownList s 都包含预先填充的值!

检查模型,仅在AirLineCode1中设置的值。检查了ViewBag,没有选中SelectListItems。所以我认为ViewBag必须保持参考。所以我将代码更改为:

ViewBag.AirLines = PopulateAirlines(user);
ViewBag.AirLines2 = PopulateAirlines(user);
ViewBag.AirLines3 = PopulateAirlines(user);
轰隆隆,固定。问题是PopulateAirlines是一个昂贵的过程!

问题是ViewBag似乎在维护3 SelectListItem List之间的引用。如何阻止它执行此操作,仍然只能拨打PopulateAirlines(user);

我尝试了以下代码,这完全爆炸了:

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'的ViewData项   有'AirlineCode2'键。

什么?!

1 个答案:

答案 0 :(得分:1)

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

IEnumerable<SelectListItem> airLines = PopulateAirlines(user);
ViewBag.AirLines = airLines;
ViewBag.AirLines2 = airLines;
ViewBag.AirLines3 = airLines;

所有ViewBag属性都指的是同一个列表。因此,对列表的更改将反映何时引用任何属性。当您调用PopulateAirlines()方法时,您将创建3个不同的列表。

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