DropDownListFor不使用重复项(List <t>)</t>绑定到编辑视图

时间:2010-08-17 10:35:37

标签: 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);
    }

这是来自控制器的代码。

这是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的下拉列表,但是,此下拉列表获取发送的值物体。它保留了它的默认标准值,这是'selectlist'

中的第一项

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

<%= Html.TextBoxFor(model => model.Vragen[i].Evvr_Type)%>

然后文本框确实获得了值。所以问题是dropdownvalue不会改变它的初始值...... MVC中的bug?

仅供参考,这是对象看起来如何发送到视图:

        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; }
            }
        }

1 个答案:

答案 0 :(得分:14)

看来这确实是一个错误或在ASP.NET MVC 2.至少不一致我已经研究它的源,发现什么InputHelper()方法从TextBoxFor称为()辅助接收与

计算默认值
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))%>
在这种情况下,

ViewData [“vraagt​​ype”]不必包含SelectListItem的对象,任何IEnumerable就足够了。您可以根据需要检查SelectList()方法说明。