DropDownListFor 沒有綁定到帶有重複項的編輯視圖 (List<T>)
事情就是這樣。我有一個編輯視圖,當我打開它時它不會綁定下拉列表的值。
[NonAction] public List<SelectListItem> VraagType() { List<SelectListItem> l = new List<SelectListItem>(); SelectListItem a = new SelectListItem(); SelectListItem b = new SelectListItem(); a.Text = "Meerkeuze"; a.Value = "M"; b.Text = "Open"; b.Value = "O"; l.Add(a); l.Add(b); return l; } [NonAction] public List<SelectListItem> getSchalen() { return _db.EvalSchaals.ToList().ToSelectList(q => q.Sch_Naam, q => q.Sch_ID.ToString(), q => q.Sch_ID == -1).ToList(); } public ActionResult Edit(int id) { ViewData["vraagtype"] = VraagType(); ViewData["schaal"] = getSchalen(); EvalVragenBlok evb = _db.EvalVragenBloks.First(q => q.Vrbl_ID == id); List<EvalVragen> ev = _db.EvalVragens.Where(q => q.Vrbl_ID == id).ToList(); FlatEvalVragenBlok fevb = Mapper.Map<EvalVragenBlok, FlatEvalVragenBlok>(evb); fevb.Vragen = new List<FlatEvalVragen>(); return View(fevb); }這是來自控制器的程式碼。
這是來自 Edit.aspx 視圖的程式碼
<h2> Edit</h2> <% using (Html.BeginForm()) {%> <%: Html.ValidationSummary(true) %> <fieldset> <legend>Fields</legend> <legend>Fields</legend> <div class="editor-label"> <%: Html.LabelFor(model => model.Vrbl_Titel) %> </div> <div class="editor-field"> <%: Html.TextBoxFor(model => model.Vrbl_Titel) %> <%: Html.ValidationMessageFor(model => model.Vrbl_Titel) %> </div> <div class="editor-label"> <%: Html.LabelFor(model => model.Sch_ID) %> </div> <div class="editor-field"> <%: Html.DropDownListFor(model => model.Sch_ID, ViewData["schaal"] as List<SelectListItem>, "Selecteer een schaal...") %> <%: Html.ValidationMessageFor(model => model.Sch_ID) %> </div> <%= Html.ValidationMessageFor(model => model.Vragen) %> <table id="vragentbl"> <tr> <th> </th> <th> Vraag </th> <th> Soort </th> </tr> <% if (Model.Vragen != null) { %> <% for (int i = 0; i < Model.Vragen.Count; i++) { %> <tr> <td> <%=i + 1%> </td> <td> <%= Html.TextBoxFor(model => model.Vragen[i].Evvr_Vraag, new { style = "width:400px" })%><br /> <%= Html.ValidationMessageFor(model => model.Vragen[i].Evvr_Vraag)%> </td> <td> <%= Html.DropDownListFor(model => model.Vragen[i].Evvr_Type, ViewData["vraagtype"] as List<SelectListItem>, new { style = "width:95px" })%><br /> <%= Html.ValidationMessageFor(model => model.Vragen[i].Evvr_Type)%> </td> </tr> <% } } %> <tr> <td> </td> <td> <a id="addnew" href="#">Voeg extra keuze toe</a> </td> <td> </td> </tr> </table> <p> <input type="submit" value="Save" /> </p> </fieldset> <% } %>我有 2 個 List 。其中1個在表單的非重複部分(Schalen),另一個(VraagType)在重複部分內部。
對於 Schalen 來說,一切正常。我打開編輯視圖,所有欄位都按原樣填寫。Vrbl_Titel 有它的值,Sch_ID 的下拉列表有它從我與視圖一起發送的對象接收到的值,該對象來自數據庫。
問題在於重複部分。model.Vragen 的文本框
$$ i $$.Evvr_Vraag 獲取它的值,以及 model.Vragen 的下拉列表$$ i $$.Evvr_Type 已顯示,但是,此下拉列表未獲取在對像中發送的值。它保持它的預設標準值,這是“選擇列表”中的第一項 我如何從我的“Vragen”對像中獲取我的價值,進入下拉列表。如果我把值放在一個簡單的文本框中
<%= Html.TextBoxFor(model => model.Vragen[i].Evvr_Type)%>然後文本框確實獲得了值。所以問題是下拉值不會改變它的初始值……MVC中的錯誤?
僅供參考,這是發送到視圖的對象的外觀:
namespace MVC2_NASTEST.Models { public partial class FlatEvalVragenBlok { public int Vrbl_ID { get; set; } public int Sch_ID { get; set; } public string Vrbl_Titel { get; set; } public List<FlatEvalVragen> Vragen { get; set; } } } namespace MVC2_NASTEST.Models { public partial class FlatEvalVragen { public int Evvr_ID { get; set; } public int Vrbl_ID { get; set; } public int Evvr_rang { get; set; } public string Evvr_Vraag { get; set; } public char Evvr_Type { get; set; } } }
看來這確實是 ASP.NET MVC 2 中的一個錯誤或至少不一致。我檢查了它的原始碼,發現從 TextBoxFor() 助手呼叫的 InputHelper() 方法接收預設值計算
ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData).Model但是從 DropDownListFor() 助手呼叫的 SelectInternal() 方法只接收使用 ExpressionHelper.GetExpressionText() 方法找到的控制項的名稱。
因此 SelectInternal() 嘗試使用 MVC 1 中的 ViewData.Eval() 方法查找預設值。眾所周知,此方法無法通過數字索引從數組中提取值。
所以在你的情況下適用
<%: Html.DropDownListFor(model => model.Sch_ID) %> <%= Html.TextBoxFor(model => model.Vragen[i].Evvr_Type)%>但不是
<%: Html.DropDownListFor(model => model.Vragen[i].Evvr_Type) %>因為它相當於
<%: Html.DropDownList("Vragen[" + i + "].Evvr_Type") %>同時我想再次強調什麼
<%= Html.TextBoxFor(model => model.Vragen[i].Evvr_Type)%>不等於
<%= Html.TextBox("model.Vragen[" + i + "].Evvr_Type")%>因為後者即使在 MVC 2 中也無法綁定預設值。
可能的解決方法
首先。由於 SelectInternal() 還檢查 ModelState 字典,因此您可以在返回視圖之前填充此字典。
for (int i=0; i < fevb.Vragen.Count(); i++) ModelState.Add("Vragen[" + i + "].Evvr_Type", new ModelState { Value = new ValueProviderResult(fevb.Vragen[i].Evvr_Type, null, CultureInfo.CurrentCulture) });這將在發布後由 MVC 自己完成,因此您應該只在第一次手動操作。
第二。代替
<%= Html.DropDownListFor(model => model.Vragen[i].Evvr_Type, ViewData["vraagtype"] as List<SelectListItem>)%>利用
<%= Html.DropDownListFor(model => model.Vragen[i].Evvr_Type, new SelectList(ViewData["vraagtype"] as IEnumerable, "Value", "Text", Model.Vragen[i].Evvr_Type))%>查看數據
$$ “vraagtype” $$在這種情況下不必包含 SelectListItem 的對象,任何 IEnumerable 就足夠了。如有需要,您可以查看 SelectList() 方法說明。