DropDownListFor上编辑视图带有重复项目不具约束力(列表< T>) [英] DropDownListFor not binding on Edit View with repeating items (List<T>)

查看:169
本文介绍了DropDownListFor上编辑视图带有重复项目不具约束力(列表< T>)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

下面是事情。我有一个编辑观点,当我打开它犯规绑定的下拉列表中的价值。

  [无为]
    公开名单< SelectListItem> VraagType(){
        清单< SelectListItem> L =新的List< SelectListItem>();
        SelectListItem一个=新SelectListItem();
        SelectListItem B =新SelectListItem();        a.Text =Meerkeuze;
        a.value中=M;        b.Text =打开;
        b.Value =O;        l.Add(一);
        l.Add(二);        返回升;
    }    [无为]
    公开名单< SelectListItem> getSchalen(){
        返回_db.EvalSchaals.ToList()ToSelectList。(Q => q.Sch_Naam,Q => q.Sch_ID.ToString()中,q => q.Sch_ID == -1).ToList();
    }    公众的ActionResult编辑(INT ID){
        计算机[vraagt​​ype] = VraagType();
        计算机[schaal] = getSchalen();        EvalVragenBlok EVB = _db.EvalVragenBloks.First(Q => q.Vrbl_ID == ID);
        清单< EvalVragen> EV = _db.EvalVragens.Where(Q => q.Vrbl_ID ==内径).ToList();        FlatEvalVragenBlok fevb = Mapper.Map< EvalVragenBlok,FlatEvalVragenBlok>(EVB);
        fevb.Vragen =新的List< FlatEvalVragen>();        返回查看(fevb);
    }

这是从控制器code。

下面是从Edit.aspx视图

在code

 < H2>
            编辑< / H>
        &下;使用%(Html.BeginForm()){%GT;
        <%:Html.ValidationSummary(真)%GT;
        <&字段集GT;
            <传奇>&领域LT; /传说>
    <传奇>&领域LT; /传说>
            < D​​IV CLASS =编辑标记>
                <%:Html.LabelFor(型号=> model.Vrbl_Titel)%GT;
            < / DIV>
            < D​​IV CLASS =主编场>
                <%:Html.TextBoxFor(型号=> model.Vrbl_Titel)%GT;
                <%:Html.ValidationMessageFor(型号=> model.Vrbl_Titel)%GT;
            < / DIV>
            < D​​IV CLASS =编辑标记>
                <%:Html.LabelFor(型号=> model.Sch_ID)%GT;
            < / DIV>
            < D​​IV CLASS =主编场>
                <%:Html.DropDownListFor(型号=> model.Sch_ID,计算机[schaal]作为名单< SelectListItem>中Selecteer EEN schaal ...)%GT;
                <%:Html.ValidationMessageFor(型号=> model.Sch_ID)%GT;
            < / DIV>
            <%= Html.ValidationMessageFor(型号=> model.Vragen)%GT;
            <表ID =vragentbl>
                &所述; TR>
                    <第i个
                    < /第i
                    <第i个
                        Vraag
                    < /第i
                    <第i个
                        Soort
                    < /第i
                < / TR>
                <如果%(!Model.Vragen = NULL){%GT;
                <%的for(int i = 0; I< Model.Vragen.Count;我++){%GT;
                &所述; TR>
                    &所述; TD>
                        &下;(%)= I + 1%GT;
                    < / TD>
                    &所述; TD>
                        <%= Html.TextBoxFor(型号=> model.Vragen [I] .Evvr_Vraag,新{风格=宽度:400像素})%GT;< BR />
                        <%= Html.ValidationMessageFor(型号=> model.Vragen [I] .Evvr_Vraag)%GT;
                    < / TD>
                    &所述; TD>
                        <%= Html.DropDownListFor(型号=> model.Vragen [I] .Evvr_Type,计算机[vraagt​​ype]作为列表与LT; SelectListItem>中新{风格=宽度:95px})%>< BR />
                        <%= Html.ValidationMessageFor(型号=> model.Vragen [I] .Evvr_Type)%GT;
                    < / TD>
                < / TR>
                <%}
                   }%GT;
                &所述; TR>
                    &所述; TD>
                    < / TD>
                    &所述; TD>
                        &下;一个ID =的AddNew的href =#> Voeg额外keuze脚趾下; / A>
                    < / TD>
                    &所述; TD>
                    < / TD>
                < / TR>
            < /表>
            &所述p为H.;
                <输入类型=提交值=保存/>
            &所述; / P>
        < /字段集>
        <%}%GT;

我有2个清单的。其中1是形式(Schalen)的非重复部分,另一种(VraagType)是内部的重复的一部分。

有关Schalen,一切工作正常。我打开编辑视图,并填写了所有字段像它应该是。该Vrbl_Titel有它的价值,Sch_ID的下拉有它从我的观点,这些来自DB发送的对象收到的值。

问题在于重复的部分。
为model.Vragen文本框[I] .Evvr_Vraag GET是它的价值,并显示了model.Vragen [I] .Evvr_Type下拉,但是,这种下拉的获取这是在发送的值物体。它保持它的默认标准值,这是在选择列表

的第一项

如何让我的价值从我的'Vragen'对象,进入下拉菜单。如果我把价值在一个简单的文本框

 <%= Html.TextBoxFor(型号=> model.Vragen [I] .Evvr_Type)%GT;

然后文本框确实获得的价值。所以问题是,dropdownvalue并没有改变形成它的初始值...臭虫MVC?

只是为信息,这是对象(S)看怎么送到观点:

 命名空间MVC2_NASTEST.Models {            公共部分类FlatEvalVragenBlok {
                公众诠释Vrbl_ID {搞定;组; }
                公众诠释Sch_ID {搞定;组; }
                公共字符串Vrbl_Titel {搞定;组; }
                公开名单< FlatEvalVragen> Vragen {搞定;组; }
            }
        }        命名空间MVC2_NASTEST.Models {            公共部分类FlatEvalVragen {
                公众诠释Evvr_ID {搞定;组; }
                公众诠释Vrbl_ID {搞定;组; }
                公众诠释Evvr_rang {搞定;组; }
                公共字符串Evvr_Vraag {搞定;组; }
                公共焦炭Evvr_Type {搞定;组; }
            }
        }


解决方案

看来这真的是一个错误或在ASP.NET MVC 2。至少我的不一致已经研究它的来源,发现从什么TextBoxFor所谓InputHelper()方法()辅助接收与计算的默认值

  ModelMetadata.FromLambdaEx pression(如pression,htmlHelper.ViewData)。型号

从DropDownListFor名为

但SelectInternal()方法()辅助接收具有防爆pressionHelper.GetEx pressionText()方法找到了控制的只是一个名字。

所以SelectInternal()试图利用MVC 1 ViewData.Eval()方法,据了解这种方法是不能够通过数字索引从数组中提取值怎么找到默认值。

所以你的情况适用

 <%:Html.DropDownListFor(型号=> model.Sch_ID)%GT;
<%= Html.TextBoxFor(型号=> model.Vragen [I] .Evvr_Type)%GT;

而不是

 <%:Html.DropDownListFor(型号=> model.Vragen [I] .Evvr_Type)%GT;

因为它等同于

 <%:Html.DropDownList(Vragen [+ I +] .Evvr_Type)%>

同时我想再次强调什么

 <%= Html.TextBoxFor(型号=> model.Vragen [I] .Evvr_Type)%GT;

不等同于

 <%= Html.TextBox(model.Vragen [+ I +] .Evvr_Type)%>

,因为后者甚至在MVC 2不能绑定默认值。

可能的解决方法

第一。由于SelectInternal()也检查的ModelState字典可以填补这一回字典视图前。

 的for(int i = 0; I< fevb.Vragen.Count();我++)
    ModelState.Add(Vragen [+ I +] .Evvr_Type,新的ModelState
    {
        值=新ValueProviderResult(fevb.Vragen [I] .Evvr_Type,空,
            CultureInfo.CurrentCulture)
    });

这将MVC自己完成从后门柱,所以你应该做手工只有第一次。

。而不是

 <%= Html.DropDownListFor(型号=> model.Vragen [I] .Evvr_Type,
    计算机[vraagt​​ype]作为名单< SelectListItem>)%GT;

使用

 <%= Html.DropDownListFor(型号=> model.Vragen [I] .Evvr_Type,
    新的SelectList(计算机[vraagt​​ype]为IEnumerable,值,文本,
        Model.Vragen [I] .Evvr_Type))%GT;

计算机[vraagt​​ype]在这种情况下,不必包含SelectListItem的目的,任何IEnumerable的就足够了。您可以为您在需要的情况下的SelectList()方法的描述。

Here is the thing. I have an Edit view, which doesnt bind the dropdowns' value when I open it.

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

this is the code from the controller.

here is the code from the Edit.aspx view

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

I have 2 List 's. 1 of them is in the non-repeating part of the form (Schalen), the other one (VraagType) is Inside the repeating part.

for Schalen, everything works fine. i open the edit view, and all fields are filled in like it should be. the Vrbl_Titel has its value, and the dropdown of Sch_ID has the value it received from the object which i sent with the view, which came from the DB.

The problem lies in the repeating part. the textbox for model.Vragen[i].Evvr_Vraag get's its value, and the dropdown for model.Vragen[i].Evvr_Type is shown, however, this dropdown does not get the value which was sent in the object. it keeps it's default standard value, which is the first item in the 'selectlist'

how do i get my value from my 'Vragen' object, into the dropdown. if i put the value in a simple textbox

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

then the textbox does get the value. so the problem is that the dropdownvalue doesnt change form it's initial value... bug in MVC?

just for info, this is how the object(s) look sent to the view:

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

解决方案

It seems this is really a bug or at least inconsistency in ASP.NET MVC 2. I have examined its source and found what InputHelper() method called from TextBoxFor() helper receives default value calculated with

ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData).Model

But SelectInternal() method called from DropDownListFor() helper receives only a name of a control found with ExpressionHelper.GetExpressionText() method.

So SelectInternal() tries to find default value using ViewData.Eval() method from MVC 1. It's known what this method isn't able to extract values from arrays by numeric index.

So in your case are applicable

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

but not

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

because it's equivalent to

<%: Html.DropDownList("Vragen[" + i + "].Evvr_Type") %>

At the same time I want to emphasize again what

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

isn't equivalent to

<%= Html.TextBox("model.Vragen[" + i + "].Evvr_Type")%>

because latter even in MVC 2 can't bind default value.

Possible workarounds

First. Since SelectInternal() also checks ModelState dictionary you can fill this dictionary before returning the view.

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

This will be done by MVC itself after from post, so you should do it manually only first time.

Second. Instead of

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

use

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

ViewData["vraagtype"] in this case doesn't have to contain objects of SelectListItem, any IEnumerable is enough. You may check SelectList() method description in case of need.

这篇关于DropDownListFor上编辑视图带有重复项目不具约束力(列表&LT; T&GT;)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆