[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个列表.其中1个是不重复部分的形式(沙伦),另一个(VraagType)在重复部分内.
对于沙伦来说,一切都很好.我打开编辑视图,所有的字段都是这样填充的. Vrbl_Titel具有其值,并且Sch_ID的下拉列表具有从我从DB发送的视图中发送的对象接收到的值.
问题在于重复部分.
model.Vragen [i] .vvr_Vraag的文本框是它的值,并显示了model.Vragen [i] .Evvr_Type的下拉列表,但是这个下拉列表没有获得在对象中发送的值.它保持默认标准值,这是’选择列表’中的第一个项目
如何从我的“Vragen”对象获取我的价值,进入下拉列表.如果我把值放在一个简单的文本框中
<%= Html.TextBoxFor(model => model.Vragen[i].Evvr_Type)%>
那么文本框确实得到了这个值.所以问题是,dropdownvalue不会改变它的初始值… 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; } } }
解决方法
ModelMetadata.FromLambdaExpression(expression,htmlHelper.ViewData).Model
但是从DropDownListFor()helper调用的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))%>
ViewData [“vraagtype”]在这种情况下不必包含SelectListItem的对象,任何IEnumerable就足够了.您可以在需要时检查SelectList()方法描述.