MVC Toolkit 部分已发现bug的根治方案 Part(1)

    这里我只说MVC Toolkit。
    第一因为MVC Toolkit bug确实别较多,第二因为我把整个"MVC"说多了,又会有朋友误解我对MVC和WebForm的看法(其实我觉得两个各有所长,没有说哪个不好的意思,但是有缺点TNT2就会尽我所发现说出来,哪怕被拍砖也算是一种交流。顺便再次真心感谢收有与我观点碰撞出火花的朋友!)。
   
    言归正传。

    时间关系,这里只讲一个让我头痛了一晚上的bug。
    如果你使用Html.Select()的话,会发现一个很奇怪的现象:并不是所有提供的重写方案里面你都提供了htmlAttributes(用以输入onclick之类的属性),只有最有一条(6 of 6)提供了。不管怎么样,我们宽容一点,把前面的5个乖乖输完,使用htmlAttributes,这个字段我输入了这样的代码:

MVC Toolkit 部分已发现bug的根治方案 Part(1)new { onchange = "checkMiniCycle();" }

    意思很明白,我需要在这个select被改变选项的时候,执行checkMiniCycle()这段客户端js命令。
    结果没有反应,我看了客户端的HTML源代码。我希望看到的当然是select中有这样一段:onchange = "checkMiniCycle();"。然而取而代之的是这么一串:

MVC Toolkit 部分已发现bug的根治方案 Part(1)IsReadOnly="False" IsFixedSize="False" IsSynchronized="False" Keys="System.Collections.Hashtable+KeyCollection" Count="1" Values="System.Collections.Hashtable+ValueCollection" SyncRoot="System.Object" 


    PS:为了方便大家理解,我只把对应的这一段取出来。其实一开始我还不知道是他输出错了,以为这个是Html.Select()像服务器空间一样自动生成出来的代码,而我的onclick没有输出。通过增加参数等等测试,我发现Count="1"(上面标为红色)随之增加,于是我通过种种迹象断定它输出了整个htmlAttributes(其实就是一个HashTable)的参数,而不是htmlAttributes内部分割后的参数。这里就耽误了我半天。
    
    于是我Reflect了MVCToolkit.dll(直接找源代码也一样):
MVC Toolkit 部分已发现bug的根治方案 Part(1)

    找到了Html.Select()第六种方法的代码:
MVC Toolkit 部分已发现bug的根治方案 Part(1)

因为和代码一样,我把源代码发出来(有注释):

 1MVC Toolkit 部分已发现bug的根治方案 Part(1)MVC Toolkit 部分已发现bug的根治方案 Part(1)/**//// <summary>
 2MVC Toolkit 部分已发现bug的根治方案 Part(1)        /// Creates an HTML Select drop-down based on the passed-in datasource.
 3MVC Toolkit 部分已发现bug的根治方案 Part(1)        /// </summary>
 4MVC Toolkit 部分已发现bug的根治方案 Part(1)        /// <param name="dataSource">IEnumerable, IQueryable, DataSet, DataTable, or IDataReader</param>
 5MVC Toolkit 部分已发现bug的根治方案 Part(1)        /// <param name="htmlName">The name of the control for the page</param>
 6MVC Toolkit 部分已发现bug的根治方案 Part(1)        /// <param name="textField">The datasource field to use for the the display text</param>
 7MVC Toolkit 部分已发现bug的根治方案 Part(1)        /// <param name="valueField">The datasource field to use for the the control value</param>
 8MVC Toolkit 部分已发现bug的根治方案 Part(1)        /// <param name="selectedValue">The value that should be selected</param>
 9MVC Toolkit 部分已发现bug的根治方案 Part(1)        /// <param name="htmlAttributes">Any attributes you want set on the select tag. Use anonymous-type declaration for this: new{class=cssclass}</param>

10MVC Toolkit 部分已发现bug的根治方案 Part(1)        public static string Select(this HtmlHelper helper, string htmlName, object dataSource, string textField,
11MVC Toolkit 部分已发现bug的根治方案 Part(1)MVC Toolkit 部分已发现bug的根治方案 Part(1)            string valueField, object selectedValue, int size, bool multiple, object htmlAttributes) MVC Toolkit 部分已发现bug的根治方案 Part(1){
12MVC Toolkit 部分已发现bug的根治方案 Part(1)            //input formats
13MVC Toolkit 部分已发现bug的根治方案 Part(1)MVC Toolkit 部分已发现bug的根治方案 Part(1)            string selectFormat = "\t<select name=\"MVC Toolkit 部分已发现bug的根治方案 Part(1){0}\" id=\"MVC Toolkit 部分已发现bug的根治方案 Part(1){0}\" {1}>" + Environment.NewLine + "{2}" + Environment.NewLine + "\t</select>";
14MVC Toolkit 部分已发现bug的根治方案 Part(1)MVC Toolkit 部分已发现bug的根治方案 Part(1)            string optionFormat = "\t\t<option value=\"MVC Toolkit 部分已发现bug的根治方案 Part(1){0}\" {1}>{2}</option>" + Environment.NewLine;
15MVC Toolkit 部分已发现bug的根治方案 Part(1)
16MVC Toolkit 部分已发现bug的根治方案 Part(1)            Hashtable setHash = HtmlExtensionUtility.GetPropertyHash(htmlAttributes);
17MVC Toolkit 部分已发现bug的根治方案 Part(1)
18MVC Toolkit 部分已发现bug的根治方案 Part(1)            //output
19MVC Toolkit 部分已发现bug的根治方案 Part(1)            StringBuilder sbOptions = new StringBuilder();
20MVC Toolkit 部分已发现bug的根治方案 Part(1)            DataTable tbl = MvcControlDataBinder.EvalDataSource(dataSource, textField, valueField);
21MVC Toolkit 部分已发现bug的根治方案 Part(1)
22MVC Toolkit 部分已发现bug的根治方案 Part(1)            //loop the source
23MVC Toolkit 部分已发现bug的根治方案 Part(1)MVC Toolkit 部分已发现bug的根治方案 Part(1)            foreach (DataRow dr in tbl.Rows) MVC Toolkit 部分已发现bug的根治方案 Part(1){
24MVC Toolkit 部分已发现bug的根治方案 Part(1)                string selectedFlag = string.Empty;
25MVC Toolkit 部分已发现bug的根治方案 Part(1)                string thisText = dr[1].ToString();
26MVC Toolkit 部分已发现bug的根治方案 Part(1)                string thisValue=dr[0].ToString();
27MVC Toolkit 部分已发现bug的根治方案 Part(1)
28MVC Toolkit 部分已发现bug的根治方案 Part(1)MVC Toolkit 部分已发现bug的根治方案 Part(1)                if (selectedValue != nullMVC Toolkit 部分已发现bug的根治方案 Part(1){
29MVC Toolkit 部分已发现bug的根治方案 Part(1)                    if (HtmlExtensionUtility.AreEqual(selectedValue, dr[0]))
30MVC Toolkit 部分已发现bug的根治方案 Part(1)                        selectedFlag = " selected=\"true\" ";
31MVC Toolkit 部分已发现bug的根治方案 Part(1)                }

32MVC Toolkit 部分已发现bug的根治方案 Part(1)                sbOptions.AppendFormat(optionFormat, helper.Encode(thisValue.ToString()), selectedFlag, helper.Encode(thisText));
33MVC Toolkit 部分已发现bug的根治方案 Part(1)            }

34MVC Toolkit 部分已发现bug的根治方案 Part(1)
35MVC Toolkit 部分已发现bug的根治方案 Part(1)            string attributeList = string.Empty;
36MVC Toolkit 部分已发现bug的根治方案 Part(1)            if (setHash != null)
37MVC Toolkit 部分已发现bug的根治方案 Part(1)                attributeList = setHash.ToAttributeList();
38MVC Toolkit 部分已发现bug的根治方案 Part(1)
39MVC Toolkit 部分已发现bug的根治方案 Part(1)            if (multiple)
40MVC Toolkit 部分已发现bug的根治方案 Part(1)                attributeList += " multiple ";
41MVC Toolkit 部分已发现bug的根治方案 Part(1)
42MVC Toolkit 部分已发现bug的根治方案 Part(1)            if(size>0)
43MVC Toolkit 部分已发现bug的根治方案 Part(1)                attributeList += " size= "+size.ToString();
44MVC Toolkit 部分已发现bug的根治方案 Part(1)
45MVC Toolkit 部分已发现bug的根治方案 Part(1)            return string.Format(selectFormat, htmlName, attributeList, sbOptions.ToString());
46MVC Toolkit 部分已发现bug的根治方案 Part(1)        }

47MVC Toolkit 部分已发现bug的根治方案 Part(1)

    问题就出在上面红色的两行,也不知道是我机子问题(不太可能吧)还是大家也这样,我把这些直接在aspx中输出,也是那一串乱七八糟的代码。于是确定了问题出自这里。

    我把这两行分别改成这样:

MVC Toolkit 部分已发现bug的根治方案 Part(1)var setHash = htmlAttributes.ToAttributeList();
MVC Toolkit 部分已发现bug的根治方案 Part(1)
MVC Toolkit 部分已发现bug的根治方案 Part(1)attributeList 
= setHash;
    PS:时间原因我没有测试上面的if判断是否多余或者是不是还有更高效的方法,这里只提供一种解决思路

    接下去编译,覆盖项目中的DLL,重新编译,运行。终于成功了!

    我举这个例子只是因为我今天就在这个Html.Select()这里被卡住了,其他的如.TextBox等等可能也存在类似的问题,在此先提供着一种解决方案。希望大家少走弯路,遇到这个问题就跳过或者用类似的方法修正

这里提供修改过Html.Select()属性bug的MVCToolkit.dll下载:
MVCToolkit.rar

    欢迎大家补充讨论^_^

 

QQ:498977166

http://szw.cnblogs.com/
研究、探讨.NET开发
转载请注明出处和作者,谢谢!

 

MVC Toolkit 部分已发现bug的根治方案 Part(1)
Senparc官方教程《微信开发深度解析:微信公众号、小程序高效开发秘籍》,耗时2年精心打造的微信开发权威教程,点击这里,购买正版

 

上一篇:Jenkins持久化集成使用


下一篇:为 MVC 和 Web Form 正名的【第二份】“大字报”