坚持MVC DropDownLists选定值(Persisting Selected Value i

2019-10-18 01:25发布

我是新来的MVC,但我一直都在这,阅读所有的文档和所有的问题,所有的博客文章,我可以找到,所有我做的是围绕轴得到完全包裹。

我试图做一个“创建”动作和视图。 我的数据项是相对直线前进,共同:我有一个下拉列表和一个文本框。 就我而言,我创建一个用户接触渠道,电子邮件和textmsg之间的下拉框中选择,然后在文本框中输入相关的联系信息,无论是中规中矩的电子邮件地址或手机号码。

这里有一个我的视图页(略简化形式):

 <tr>
     <td><%= Html.DropDownList("ChannelDescription", Model.ChannelDescription, "Select a Channel", new { id = "ChannelDDL", onchange="ChannelDDLChanged()" })%>
         <br />
         <%= Html.ValidationMessage("ChannelDescription", "Please Select a Channel") %>
      </td>
      <td>
           <%= Html.TextBox("SubscriberNotificationAddr") %> <br />
           <%= Html.ValidationMessage("SubscriberNotificationAddr", "Please enter a contact address or number") %>
       </td>
  </tr>

我使用的是强类型的ViewData模型,而不是使用的ViewDataDictionary。 该ChannelDescription元素是的SelectList,这是与选项列表,并没有选择初始化。

的形式时,将数据输入到的形式,并且所述数据从由所述控制器的形式提取的初始显示变为细。

我的问题是:如果数据包含错误,如恶意形成的电子邮件地址或手机号码,我一定要回到观点,我还没有成功地让下拉列表中选择重新显示。 所述ChannelDescription元件是与用户的选择作为所选择的项目中的控制器重新创建。 我已经在该行的视图中设置断点,并验证项目列表中选定的元素已经选定的属性设置为true,但它仍然显示默认的“选择频道”。

这似乎是这将是一个很常见的情况,不应该这么难。 我究竟做错了什么?

仅供参考,这是MVC 1.0(发行版),Windows 7和VS 2008,火狐3.5.2下运行。

Answer 1:

查看上面的回答后,我想检查出来,因为所有的例子我已经看到了,的确,使用的ViewDataDictionary,而不是一个强类型ViewDataModel。

所以,我做了一些实验。 我构成,即使用普通的ViewDataDictionary,并在由名为键传递的值非常简单的图。 它坚持所选项目就好了。 然后我剪切和粘贴该视图(和控制器)到另一个,只改变什么必要切换到一个强类型的ViewData模型。 罗,不料,它也坚持选择的项目。

那么还有什么是我的简单测试和我的应用程序之间有什么不同? 在我的测试中,我用了简单的“Html.DropDownList(”名“‘optionLabel’)”。 然而,在我的应用程序,我需要添加HTML属性,并且包括HtmlAttributes唯一可用的重载还包括选择列表中。

事实证明,使用选择列表参数DropDownList的过载是爆发了! 综观下载MVC的源代码,当DropDownList会调用只是一个名称或姓名和optionLabel,它结束了从ViewData的检索目标选择列表,然后通过下面的调用调用私有SelectInternal方法:

    return SelectInternal(htmlHelper, optionLabel, name, selectList, true /* usedViewData */, false /* allowMultiple */, (IDictionary<string, object>)null /* htmlAttributes */);

但是,如果它被称为一个选择列表的参数,它结束了以下内容:

   return SelectInternal(htmlHelper, optionLabel, name, selectList, false /* usedViewData */, false /* allowMultiple */, htmlAttributes);

所不同的是,在第一个(这将正常工作)的“usedViewData”参数为真,而在第二个,它是假的。 这实际上是好的,但暴露在SelectInternal例行的内部缺陷。

如果usedViewData是假的,它就会从ViewData的模型对象变量“默认值”。 然而,默认值被用作虽然它是一个字符串或字符串的时候,其实什么是从ViewData的返回是的SelectList的数组。 ( IEnumerable<SelectListItem>

如果usedViewData为真,则默认值将是null或字符串。

那么,如果默认值不为空,它最终进入包含此代码块:

        foreach (SelectListItem item in selectList) {
            item.Selected = (item.Value != null) ? selectedValues.Contains(item.Value) : selectedValues.Contains(item.Text);
            newSelectList.Add(item);

选择列表的是传递在原来的SelectList,因此该项目是一个SelectListItem(字符串文本,字符串值,BOOL选择)。 但是selectedValues从默认值派生,并成为SelectLists的列表,而不是一个字符串列表。 因此,对于每个项目,它的设置基础上,selectedValues列表是否“包含” item.Value所选标志。 那么,SelectLists的名单是永远不会“遏制”的字符串,所以item.Selected永远不会被设置。 (更正:实际上,更与调试器跟踪后,我发现selectedValues从默认值由“的ToString()”呼叫衍生所以它实际上是一个字符串列表,但不是包含了我们需要的值,它。包含“System.Web.Mvc.SelectList” - 应用“的ToString()”,以类似的SelectList复杂对象的结果,结果还是一样 - 我们不会找到我们正在寻找的价值列表)。

然后,它替代了新建成的“newSelectList”原始“选择列表的”,并继续从它建立HTML。

作为cagdas(我对屠宰你的名字道歉,但我不知道如何让我的美国键盘这些字符)上面说的,我想我要建立自己的方法来代替将DropDownList的HtmlHelper的使用。 我想因为这个版本1和Release2是在Beta 2中,我们不能真正期待任何bug修复,除非我们自己动手吧?

顺便说一句,如果你追了我这么远,这个代码在src \ SystemWebMvc \的mvc \ HTML \ SelectExtensions.cs,大约行116-136



Answer 2:

我曾与布拉德·威尔逊一些讨论,从MVC团队,他对我解释说,我被误解怎么DropDownList的辅助方法,应采用(一种误解,我认为可能是相当普遍的,从我读过)。

基本上,要么放弃它在视图模型的命名参数选择列表的,让它建立在下拉列表中,从与选择适当的项目,或给它的SelectList作为一个单独的参数,让视图模型的命名参数只是值串所选项目(多个)。 如果你给它一个的SelectList参数,那么,预计命名值是字符串的字符串或列表,而不是一个的SelectList。

所以,现在你的视图模型最终有在视图中的一个概念项目(下拉列表)的两个元素。 因此,你可能有,有一个模型

string SelectedValue {get; set;}
SelectList DropDownElements { get; set;}

然后,您可以预先填充与选择的DropDownElements,但在你的模型视图结合,你只需要处理的SelectedValue元素。 看来,当我这样做的工作非常适合我。



Answer 3:

是的,我也曾经有过这么多的问题得到DropDownList的尊重所选择的项目我已经给它。

请检查我的答案在这个问题上 。 至于我还记得,那是唯一的方法,我可以得到它的工作。 通过借助ViewData的传递列表。

仅供参考,我停止使用该方法的HtmlHelper。 我现在简单地输出<select><option>标记自己与一个循环,并设置selected的物业option通过检查它自己的标签。



文章来源: Persisting Selected Value in MVC DropDownLists