时间关系,这里只讲一个让我头痛了一晚上的bug。
如果你使用Html.Select()的话,会发现一个很奇怪的现象:并不是所有提供的重写方案里面你都提供了htmlAttributes(用以输入onclick之类的属性),只有最有一条(6 of 6)提供了。不管怎么样,我们宽容一点,把前面的5个乖乖输完,使用htmlAttributes,这个字段我输入了这样的代码:
new { onchange = "checkMiniCycle();" }
意思很明白,我需要在这个select被改变选项的时候,执行checkMiniCycle()这段客户端js命令。
结果没有反应,我看了客户端的HTML源代码。我希望看到的当然是select中有这样一段:onchange = "checkMiniCycle();"。然而取而代之的是这么一串:
......
接下去编译,覆盖项目中的DLL,重新编译,运行。终于成功了!
这里我只说MVC Toolkit。
第一因为MVC Toolkit bug确实别较多,第二因为我把整个"MVC"说多了,又会有好些朋友误解我对MVC和WebForm的看法(其实我觉得两个各有所长,没有说哪个不好的意思,但是有缺点TNT2就会尽我所发现说出来,哪怕被拍砖也算是一种交流。顺便再次真心感谢收有与我观点碰撞出火花的朋友!)。
言归正传。
时间关系,这里只讲一个让我头痛了一晚上的bug。
如果你使用Html.Select()的话,会发现一个很奇怪的现象:并不是所有提供的重写方案里面你都提供了htmlAttributes(用以输入onclick之类的属性),只有最有一条(6 of 6)提供了。不管怎么样,我们宽容一点,把前面的5个乖乖输完,使用htmlAttributes,这个字段我输入了这样的代码:
new { onchange = "checkMiniCycle();" }
意思很明白,我需要在这个select被改变选项的时候,执行checkMiniCycle()这段客户端js命令。
结果没有反应,我看了客户端的HTML源代码。我希望看到的当然是select中有这样一段:onchange = "checkMiniCycle();"。然而取而代之的是这么一串:
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(直接找源代码也一样):

找到了Html.Select()第六种方法的代码:

因为和源代码一样,我把源代码发出来(有注释):
1
/**//// <summary>
2
/// Creates an HTML Select drop-down based on the passed-in datasource.
3
/// </summary>
4
/// <param name="dataSource">IEnumerable, IQueryable, DataSet, DataTable, or IDataReader</param>
5
/// <param name="htmlName">The name of the control for the page</param>
6
/// <param name="textField">The datasource field to use for the the display text</param>
7
/// <param name="valueField">The datasource field to use for the the control value</param>
8
/// <param name="selectedValue">The value that should be selected</param>
9
/// <param name="htmlAttributes">Any attributes you want set on the select tag. Use anonymous-type declaration for this: new{class=cssclass}</param>
10
public static string Select(this HtmlHelper helper, string htmlName, object dataSource, string textField,
11
string valueField, object selectedValue, int size, bool multiple, object htmlAttributes)
{
12
//input formats
13
string selectFormat = "\t<select name=\"
{0}\" id=\"
{0}\" {1}>" + Environment.NewLine + "{2}" + Environment.NewLine + "\t</select>";
14
string optionFormat = "\t\t<option value=\"
{0}\" {1}>{2}</option>" + Environment.NewLine;
15
16
Hashtable setHash = HtmlExtensionUtility.GetPropertyHash(htmlAttributes);
17
18
//output
19
StringBuilder sbOptions = new StringBuilder();
20
DataTable tbl = MvcControlDataBinder.EvalDataSource(dataSource, textField, valueField);
21
22
//loop the source
23
foreach (DataRow dr in tbl.Rows)
{
24
string selectedFlag = string.Empty;
25
string thisText = dr[1].ToString();
26
string thisValue=dr[0].ToString();
27
28
if (selectedValue != null)
{
29
if (HtmlExtensionUtility.AreEqual(selectedValue, dr[0]))
30
selectedFlag = " selected=\"true\" ";
31
}
32
sbOptions.AppendFormat(optionFormat, helper.Encode(thisValue.ToString()), selectedFlag, helper.Encode(thisText));
33
}
34
35
string attributeList = string.Empty;
36
if (setHash != null)
37
attributeList = setHash.ToAttributeList();
38
39
if (multiple)
40
attributeList += " multiple ";
41
42
if(size>0)
43
attributeList += " size= "+size.ToString();
44
45
return string.Format(selectFormat, htmlName, attributeList, sbOptions.ToString());
46
}
47
问题就出在上面红色的两行,也不知道是我机子问题(不太可能吧)还是大家也这样,我把这些直接在aspx中输出,也是那一串乱七八糟的代码。于是确定了问题出自这里。
我把这两行分别改成这样:
var setHash = htmlAttributes.ToAttributeList();

attributeList = setHash;
PS:时间原因我没有测试上面的if判断是否多余或者是不是还有更高效的方法,这里只提供一种解决思路。
接下去编译,覆盖项目中的DLL,重新编译,运行。终于成功了!
我举这个例子只是因为我今天就在这个Html.Select()这里被卡住了,其他的如.TextBox等等可能也存在类似的问题,在此先提供着一种解决方案。希望大家少走弯路,遇到这个问题就跳过或者用类似的方法修正。
这里提供修改过Html.Select()属性bug的MVCToolkit.dll下载:MVCToolkit.rar
欢迎大家补充讨论^_^
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· C#/.NET/.NET Core技术前沿周刊 | 第 29 期(2025年3.1-3.9)
· 从HTTP原因短语缺失研究HTTP/2和HTTP/3的设计差异