-----------------------------------来自网上的解决方法---------------------------------------------

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属性后前端依然不能默认选中的解决方法的更多相关文章

  1. Delphi中Menu设置Images属性后快捷按键下划线被隐藏解决方法

    现象:MainMenu设置Images属性后,看不到快捷按键的下划线,如:新建(&N) 分析:VCL中Menus.pas单元的代码,看到如下语句procedure TMenuItem.Adva ...

  2. dedecms设置文章分页后,标题会带有序号的解决方法

    至于删除分页后标题后面的序号,找到include/arc.archives.class.php 打开,找到 if($i>1) $this->Fields['title'] = $this- ...

  3. jquery 纯JS设置select下拉框,并默认选中第一个

    //html页面<select id="payWay" class="easyui-combobox" name="payWay" s ...

  4. 【jquery】jquery 在 ie6 下无法设置 select 选中的解决方法

    本文主要解决在 ie6 下,jquery 无法设置 select 选中的问题.我们先看个例子: <!DOCTYPE HTML> <html lang="en-US" ...

  5. ComboBox控件“设置 DataSource 属性后无法修改项集合”的解决【转】

    编写Winform程序,遇到comboBox的绑定事件和索引项变更事件的冲突问题,就是“设置 DataSource 属性后无法修改项集合”的错误问题,网上查了很多,大多说在索引项变更是进行非空判断,还 ...

  6. 元素设置disabled属性后便无法向后台传值

    元素设置disabled属性后便无法向后台传值

  7. C# LIstbox 解决WinForm下ListBox控件“设置DataSource属性后无法修改项集合”的问题

    解决WinForm下ListBox控件“设置DataSource属性后无法修改项集合”的问题 分类: winform2008-05-24 02:33 2592人阅读 评论(11) 收藏 举报 winf ...

  8. 解决WinForm下ListBox控件“设置DataSource属性后无法修改项集合”

    解决WinForm下ListBox控件“设置DataSource属性后无法修改项集合” 最近更新: 2013-2-15    587   很少写WinForm程序第一次使用ListBox控件就遇到了比 ...

  9. 解决BootstrapTable设置height属性后,表格不对齐的问题

    解决BootstrapTable设置height属性后,表格不对齐的问题 2018年03月06日 09:56:54 nb7474 阅读数 5920     一般在使用BootstrapTable 插件 ...

随机推荐

  1. Nginx基本配置和作用

    nginx可以重新加载文件的.我们直接运行:nginx -s reload 配置文件有没有问题,可以直接输入:nginx -t nginx -s stop就可以关闭 但有时我们就不想它挂的时候访问另外 ...

  2. SP8093 JZPGYZ - Sevenk Love Oimaster

    传送门 广义后缀自动机-- 其实也不是很难理解,就是每次SAM插入一个串之后,插入新的串的时候,要把last重新调到1的位置,共用一些节点. 这个题我们首先要预处理出来每个状态被多少个串共用.挺暴力的 ...

  3. 图片轮播和C3动画

    值得注意的地方是:如果在图片下面的li做背景图片,可以把li上的数字或者文本设置为transparent(透明色),这样的话既可以实现轮播的定时器效果,也可以让li上有C3动画效果.如果li上的文字不 ...

  4. bzoj 3028 食物 —— 生成函数

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3028 式子很好推,详细可以看这篇博客:https://blog.csdn.net/wu_to ...

  5. javascript闭包和闭包的几种写法和用法

    什么是闭包 闭包,官方的解释是:一个拥有需要许多变量和绑定了这=这些变量的表达式(通常是一个函数),因而这些变量也是该表达式的一部分.闭包的特点: 1 作为一个函数变量的引用,当函数返回时,其处于激活 ...

  6. 五、hibernate在myeclipse中生成实体和映射

  7. 深度学习之softmax回归

    前言            以下内容是个人学习之后的感悟,转载请注明出处~ softmax回归 首先,我们看一下sigmod激活函数,如下图,它经常用于逻辑回归,将一个real value映射到(0, ...

  8. sizeToFit的学习与认知

    今天一扫前两日的坏心情,终于有心情平静下来,今天我是根据网络上的一些资料进行学习,今天学习的内容是 sizeToFit() 方法在不方便手动布局的场景中的使用. 首先感谢资料的提供者:参考1 参考2 ...

  9. linux内核中ip,tcp等头的定义(转)

    一.MAC帧头定义 /*数据帧定义,头14个字节,尾4个字节*/typedef struct _MAC_FRAME_HEADER{ char m_cDstMacAddress[6];    //目的m ...

  10. 3-3Java程序的结构

    这是类的定义 这是主方法的定义 类里面包含一个主方法,或者是主方法嵌套到我们的类里面 大括号要特别注意,通过大括号我们可以看到类和主方法的包含关系 class后面一定是跟的类的名字