MVC dropdownlist 后端设置select属性后前端依然不能默认选中的解决方法
-----------------------------------来自网上的解决方法---------------------------------------------
ASP.Net MVC的ViewBag一个坑,不要跳进去
如鹏的学习管理系统是使用ASP.net MVC 5开发的,今天一个新版本发布后网站出现一个Bug,学生在下拉列表中选中的项再加载显示的时候发现仍然没被选中。详细一点说吧:
假如有这样一个Action:
public ActionResult Index(){List persons = new List();persons.Add(new SelectListItem { Text = "腾讯", Value = "qq" });persons.Add(new SelectListItem { Text = "如鹏", Value = "rupeng", Selected = true });ViewBag.persons = persons;return View();}
Cshtml是这样的:
@Html.DropDownList("persons", (IEnumerable)ViewBag.persons)
生成的html是这样的:
腾讯如鹏
竟然第二项没有处于选中状态,太诡异了吧!
只要把DropDownList第二个参数的"persons"改成和”ViewBag.persons”的persons名字不一样就可以,比如:
@Html.DropDownList("persons1", (IEnumerable)ViewBag.persons)
这样就正确生成了:
腾讯如鹏
好诡异!!!
咋办?看源码!
DropDownList是定义在SelectExtensions扩展类中,DropDownList方法最终是调用SelectInternal方法,核心代码是这一段:
if (!flag && obj == null && !string.IsNullOrEmpty(name)){obj = htmlHelper.ViewData.Eval(name);}if (obj != null){selectList = SelectExtensions.GetSelectListWithDefaultValue(selectList, obj, allowMultiple);}
这个name参数就是我们传递给DropDownList的第一个参数"persons",上面代码主要逻辑就是:首先到ViewData中查找名字为"persons"的值,我们知道ViewData和ViewBag是一样的,所以htmlHelper.ViewData.Eval(name)取到的值就是我们在Index中定义的List()集合。GetSelectListWithDefaultValue方法的代码是:
private static IEnumerable GetSelectListWithDefaultValue(IEnumerable selectList, object defaultValue, bool allowMultiple){IEnumerable enumerable= new object[]{defaultValue};IEnumerable collection =from object value in enumerableselect Convert.ToString(value, CultureInfo.CurrentCulture);HashSet hashSet = new HashSet(collection, StringComparer.OrdinalIgnoreCase);List list = new List();foreach (SelectListItem current in selectList){current.Selected = ((current.Value != null) ? hashSet.Contains(current.Value) : hashSet.Contains(current.Text));list.Add(current);}return list;}
注意,我们的List()集合被当成defaultValue参数传递给GetSelectListWithDefaultValue方法了(why?),在方法内部又把defaultValue给 Convert.ToString()一下,变成了”System.Collections.Generic.List`1[System.Web.Mvc.SelectListItem]”这么一个玩意, GetSelectListWithDefaultValue的主要逻辑就是查找selectList中等于”System.Collections.Generic.List`1[System.Web.Mvc.SelectListItem]”的值,能找到才算见了鬼呢!!!
经过上面的分析我们还可以知道,不能让cshtml中DropDownList的第一个name参数和ViewBag中任何一个属性重名,否则还是会有问题,比如
public ActionResult Index(){List persons = new List();persons.Add(new SelectListItem { Text = "腾讯", Value = "qq" });persons.Add(new SelectListItem { Text = "如鹏", Value = "rupeng", Selected = true });ViewBag.persons = persons;ViewBag.persons1 = new string[] { };return View();}
Cshtml如下:
@Html.DropDownList("persons1", (IEnumerable)ViewBag.persons)
生成的html中第二条数据照样不会被selected
不知道微软为什么把DropDownList这么简单的一个东西搞的这么复杂,正验证了这句话“写的越多,错的越多”。当然也许微软会给出理由说我们用错了,说“It’s not a bug,It’s a feature,by design”好吧!谢特!
5楼高卿这代码,有点眼熟,,,不过尽量不用viewbag的话。。那也就viewdata的了。或者其他前端框架了。4楼Choo正确的用法是:@Html.DropDownList(quot;personsquot;, null),,这样的写法方便性体现在DropDownListFor时,model对应属性的值就会自动被选上,而不需要在构建SelectList时去确定被选值。3楼幻天芒想想也是这个问题,不过暂时没想到有说买更好的方式实现...Re: 高卿@幻天芒,亲。有个麻烦的问题麻烦下您。您能给我一个QQ么。关于rsa加密java和C#之间的问题。2楼小眼睛老鼠这是mvc的特性啊,也就是说 前端的控件 都会通过key 去viewdata 或者 viewbag作为当前控件的value,,也就是说如果你要设置 某个控件 例如 control1的value的话,那么只要在action中写成这样就好了,viewbag. control1 = ???,前端不用再在 控件里面赋值了,,这里你正好吧value当做了dropdownlist的 内部结构数据传进去了,,所以就。。。。。Re: 杨中科@小眼睛老鼠,引用这是mvc的特性啊,也就是说 前端的控件 都会通过key 去viewdata 或者 viewbag作为当前控件的value,,也就是说如果你要设置 某个控件 例如 control1的value的话,那么只要在action中写成这样就好了,viewbag. control1 = ???,前端不用再在 控件里面赋值了,,这里你正好吧value当做了dropdownlist的 内部结构数据传进去了,,所以就。。。。。,如果这样的话就太恶心了,Razor做好模板引擎的工作就行了,传给你数据、你负责展现,别搞这么多自动化的东西。架构设计的一个原则就是“Keep it simple”1楼a.thinker约定
大于配置 ,所以,你要确定asp.mvc约定了什么,,你可以试下另一种写法:,代码,var persons = new Listlt;objectgt; { new { Text = quot;腾讯quot;, Value = quot;qqquot;
-----------------------------------来自网上的解决方法---------------------------------------------

----------------------------------------自己的代码-------------------------------------------------

---------------------------------------自己的代码---------------------------------------
MVC dropdownlist 后端设置select属性后前端依然不能默认选中的解决方法的更多相关文章
- Delphi中Menu设置Images属性后快捷按键下划线被隐藏解决方法
现象:MainMenu设置Images属性后,看不到快捷按键的下划线,如:新建(&N) 分析:VCL中Menus.pas单元的代码,看到如下语句procedure TMenuItem.Adva ...
- dedecms设置文章分页后,标题会带有序号的解决方法
至于删除分页后标题后面的序号,找到include/arc.archives.class.php 打开,找到 if($i>1) $this->Fields['title'] = $this- ...
- jquery 纯JS设置select下拉框,并默认选中第一个
//html页面<select id="payWay" class="easyui-combobox" name="payWay" s ...
- 【jquery】jquery 在 ie6 下无法设置 select 选中的解决方法
本文主要解决在 ie6 下,jquery 无法设置 select 选中的问题.我们先看个例子: <!DOCTYPE HTML> <html lang="en-US" ...
- ComboBox控件“设置 DataSource 属性后无法修改项集合”的解决【转】
编写Winform程序,遇到comboBox的绑定事件和索引项变更事件的冲突问题,就是“设置 DataSource 属性后无法修改项集合”的错误问题,网上查了很多,大多说在索引项变更是进行非空判断,还 ...
- 元素设置disabled属性后便无法向后台传值
元素设置disabled属性后便无法向后台传值
- C# LIstbox 解决WinForm下ListBox控件“设置DataSource属性后无法修改项集合”的问题
解决WinForm下ListBox控件“设置DataSource属性后无法修改项集合”的问题 分类: winform2008-05-24 02:33 2592人阅读 评论(11) 收藏 举报 winf ...
- 解决WinForm下ListBox控件“设置DataSource属性后无法修改项集合”
解决WinForm下ListBox控件“设置DataSource属性后无法修改项集合” 最近更新: 2013-2-15 587 很少写WinForm程序第一次使用ListBox控件就遇到了比 ...
- 解决BootstrapTable设置height属性后,表格不对齐的问题
解决BootstrapTable设置height属性后,表格不对齐的问题 2018年03月06日 09:56:54 nb7474 阅读数 5920 一般在使用BootstrapTable 插件 ...
随机推荐
- 使用 @RequestMapping 映射请求
- 安装tensorflow-gpu出现的问题
1.Could not install packages due to an EnvironmentError: [Errno 13] Permission denied: '/usr/local/l ...
- Ubuntu18.04 安装 JDK7
直接下载jdk压缩包方式安装 1.官网下载JDK 地址: http://www.oracle.com/technetwork/articles/javase/index-jsp-138363 ...
- 5.js屏蔽方向键,兼容IE和firefox
document.onkeydown=function(e){ e=e||event; //屏蔽向左的方向键 if(e.keyCode==37){ alert('禁止向左的方向键!'); return ...
- android项目源码
[置顶] Android精品开源项目整理_V20140221(持续更新中..) 让我们回顾下2013年有哪些精品资源:Android精品开源项目整理_V20131115(持续更新中..) 引言: ...
- Dreamweaver cs6 的安装与破解
网上找的教程http://jingyan.baidu.com/article/9f7e7ec08383b26f281554f4.html,亲测无误 只需点击试用安装即可 破解只需替换amtlib.dl ...
- springmvc源码分析系列-请求处理流程
接上一篇-springmvc源码分析开头片 上一节主要说了一下springmvc与struts2的作为MVC中的C(controller)控制层的一些区别及两者在作为控制层方面的一些优缺点.今天就结合 ...
- 给source insight添加.cc的C++文件后缀识别(转载)
转自:http://blog.chinaunix.net/uid-9950859-id-99172.html 今天在读mysql代码的时候,发现.cc结尾的文件都没有添加进来,google下了,发现原 ...
- angular6 render2 & viewContentRef实践
angular 渲染层 angular一个跨平台的框架不仅仅针对的浏览器这一个平台 ElementRef 与 TemplateRef 简单的理解: ElemnetRef : 例如一个<span& ...
- TP5之发送邮件
1.下载扩展,vendor\phpmailer 文件结构: 2.话不多说,上代码 注意点: · 需要提前开通对应邮箱的SMTP服务 · $mail->Host = " & ...