从我的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'键。
什么?!
答案 0 :(得分:1)
可能是因为在这段代码中:
IEnumerable<SelectListItem> airLines = PopulateAirlines(user);
ViewBag.AirLines = airLines;
ViewBag.AirLines2 = airLines;
ViewBag.AirLines3 = airLines;
所有ViewBag
属性都指的是同一个列表。因此,对列表的更改将反映何时引用任何属性。当您调用PopulateAirlines
()方法时,您将创建3个不同的列表。
您需要制作三个单独的列表,但只使用PopulateAirlines
方法创建第一个,然后 克隆 两次。那不会那么贵。