DropDownList对于带有重复项的编辑视图没有绑定(List <T>)

Ste*_*vds 9 asp.net-mvc asp.net-mvc-2 drop-down-menu

这就是事情.我有一个编辑视图,当我打开它时,它不会绑定下拉列表的值.

    [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);
    }
Run Code Online (Sandbox Code Playgroud)

这是控制器的代码.

这是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>
        <% } %>
Run Code Online (Sandbox Code Playgroud)

我有2个List.其中1个在形式的非重复部分(Schalen),另一个(VraagType)在重复部分的内部.

对于Schalen,一切正常.我打开编辑视图,所有字段都应该填写.Vrbl_Titel具有其值,并且Sch_ID的下拉列表具有从我使用视图发送的对象接收的值,该对象来自DB.

问题在于重复部分.model.Vragen [i] .Evvr_Vraag的文本框获取其值,并显示model.Vragen [i] .Evvr_Type的下拉列表,但是,此下拉列表不会获取在对象中发送的值.它保持默认标准值,这是'选择列表'中的第一项

如何从我的'Vragen'对象中获取我的价值,进入下拉列表.如果我把值放在一个简单的文本框中

<%= Html.TextBoxFor(model => model.Vragen[i].Evvr_Type)%>
Run Code Online (Sandbox Code Playgroud)

那么文本框确实得到了价值.所以问题是下拉值不会改变它的初始值...... 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; }
            }
        }
Run Code Online (Sandbox Code Playgroud)

Ale*_*yev 14

这似乎是一个错误或至少在ASP.NET MVC 2中不一致.我检查了它的源代码,发现从TextBoxFor()帮助程序调用的InputHelper()方法接收到的默认值

ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData).Model
Run Code Online (Sandbox Code Playgroud)

但是从DropDownListFor()助手调用的SelectInternal()方法只接收使用ExpressionHelper.GetExpressionText()方法找到的控件的名称.

因此,SelectInternal()尝试使用MVC 1中的ViewData.Eval()方法查找默认值.已知此方法无法通过数字索引从数组中提取值.

所以在你的情况下是适用的

<%: Html.DropDownListFor(model => model.Sch_ID) %>
<%= Html.TextBoxFor(model => model.Vragen[i].Evvr_Type)%>
Run Code Online (Sandbox Code Playgroud)

但不是

<%: Html.DropDownListFor(model => model.Vragen[i].Evvr_Type) %>
Run Code Online (Sandbox Code Playgroud)

因为它相当于

<%: Html.DropDownList("Vragen[" + i + "].Evvr_Type") %>
Run Code Online (Sandbox Code Playgroud)

与此同时,我想再次强调一下

<%= Html.TextBoxFor(model => model.Vragen[i].Evvr_Type)%>
Run Code Online (Sandbox Code Playgroud)

不等于

<%= Html.TextBox("model.Vragen[" + i + "].Evvr_Type")%>
Run Code Online (Sandbox Code Playgroud)

因为后者即使在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) 
    });
Run Code Online (Sandbox Code Playgroud)

这将由post发布后由MVC自己完成,所以你应该只在第一次手动完成.

第二.代替

<%= Html.DropDownListFor(model => model.Vragen[i].Evvr_Type, 
    ViewData["vraagtype"] as List<SelectListItem>)%>
Run Code Online (Sandbox Code Playgroud)

使用

<%= Html.DropDownListFor(model => model.Vragen[i].Evvr_Type, 
    new SelectList(ViewData["vraagtype"] as IEnumerable, "Value", "Text",
        Model.Vragen[i].Evvr_Type))%>
Run Code Online (Sandbox Code Playgroud)

在这种情况下,ViewData ["vraagt​​ype"]不必包含SelectListItem的对象,任何IEnumerable都足够了.您可以根据需要检查SelectList()方法说明.