Java自学者论坛

 找回密码
 立即注册

手机号码,快捷登录

恭喜Java自学者论坛(https://www.javazxz.com)已经为数万Java学习者服务超过8年了!积累会员资料超过10000G+
成为本站VIP会员,下载本站10000G+会员资源,会员资料板块,购买链接:点击进入购买VIP会员

JAVA高级面试进阶训练营视频教程

Java架构师系统进阶VIP课程

分布式高可用全栈开发微服务教程Go语言视频零基础入门到精通Java架构师3期(课件+源码)
Java开发全终端实战租房项目视频教程SpringBoot2.X入门到高级使用教程大数据培训第六期全套视频教程深度学习(CNN RNN GAN)算法原理Java亿级流量电商系统视频教程
互联网架构师视频教程年薪50万Spark2.0从入门到精通年薪50万!人工智能学习路线教程年薪50万大数据入门到精通学习路线年薪50万机器学习入门到精通教程
仿小米商城类app和小程序视频教程深度学习数据分析基础到实战最新黑马javaEE2.1就业课程从 0到JVM实战高手教程MySQL入门到精通教程
查看: 342|回复: 0

MVC dropdownlist 后端设置select属性后前端依然不能默认选中的解决方法

[复制链接]
  • TA的每日心情
    奋斗
    4 天前
  • 签到天数: 802 天

    [LV.10]以坛为家III

    2053

    主题

    2111

    帖子

    72万

    积分

    管理员

    Rank: 9Rank: 9Rank: 9

    积分
    726006
    发表于 2021-5-16 14:31:04 | 显示全部楼层 |阅读模式

     

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

    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;

     

     

     

     

     

     

     

     

     

     

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

     

     

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

     

     

     

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

     

    哎...今天够累的,签到来了1...
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|手机版|小黑屋|Java自学者论坛 ( 声明:本站文章及资料整理自互联网,用于Java自学者交流学习使用,对资料版权不负任何法律责任,若有侵权请及时联系客服屏蔽删除 )

    GMT+8, 2024-11-15 16:45 , Processed in 1.057640 second(s), 28 queries .

    Powered by Discuz! X3.4

    Copyright © 2001-2021, Tencent Cloud.

    快速回复 返回顶部 返回列表