RegisterExpandoAttribute()实现缺陷

简介:

 在Framework 2.0里微软提供了一个叫ClientScriptManager的类来专门管理Page类上面的脚本注册,并且把原来Page类上提供的RegisterXXX和IsRegisterXXX等方法都置为了Obsolete。ClientScriptManager类提供了一个叫RegisterExpandoAttribute()的新方法,不过这个方法实现得太草率了。

    方法ClientScriptMarager.RegisterExpandoAttribute()有两个重载,分别是:

None.gif ClientScriptManager.RegisterExpandoAttribute (String, String, String)    
None.gif ClientScriptManager.RegisterExpandoAttribute (String, String, String, Boolean) 
    // 参数分别是:controlId, attributeName, attributeValue和encode。

    这个方法是干什么的呢?它是用来 动态的向HTML元素添加 Expando属性的,我们在Fx 1.1时代,如果要在控键的输出标签上添加Expando属性,一般的方法是使用WebControl.Attributes集合属性,并且只能添加static的literal string。而在2.0里,我们就可以使用RegisterExpandoAttribute方法来达到同样的效果,其实效果和Fx1.1中一样,只是后者更突出了动态添加的概念。

    比如在页面上放一个叫lblTest的Label控件,使用:
None.gif  this.ClientScript.RegisterExpandoAttribute("lblTest", "message", "ok.");
None.gif  this.ClientScript.RegisterExpandoAttribute("lblTest", "resulte", "'string'");
None.gif  this.ClientScript.RegisterExpandoAttribute("lblTest", "resulte", "'string'",  false); None.gif

    我们得到如下的客户端注册脚本:
ExpandedBlockStart.gif ContractedBlock.gif < script  type ="text/javascript" > dot.gif
InBlock.gif
<!--
InBlock.gif
var  lblTest  =  document.all  ?  document.all[ " lblTest " ] : document.getElementById( " lblTest " );
InBlock.giflblTest.message 
=   " ok. " ;
InBlock.giflblTest.resulte 
=   " \'string\' " ;
InBlock.giflblTest.resulte2 
=   " 'string' " ;
ExpandedBlockEnd.gif
//  -->
None.gif
</ script >

    看起来效果不错,但我为什么说它实现的很草率呢?Review一下微软的实现先:
None.gif internal  void RenderExpandoAttribute(HtmlTextWriter writer)
ExpandedBlockStart.gif ContractedBlock.gif dot.gif{
InBlock.gif     if (( this._registeredControlsWithExpandoAttributes !=  null) && ( this._registeredControlsWithExpandoAttributes.Count != 0))
ExpandedSubBlockStart.gif ContractedSubBlock.gif     dot.gif{
InBlock.gif         writer.Write("\r\n<script type=\"text/javascript\">\r\n<!--\r\n");
InBlock.gif          foreach (DictionaryEntry entry1  in  this._registeredControlsWithExpandoAttributes)
ExpandedSubBlockStart.gif ContractedSubBlock.gif          dot.gif{
InBlock.gif              string text1 = ( string) entry1.Key;
InBlock.gif             writer.Write("var ");
InBlock.gif             writer.Write(text1);
InBlock.gif             writer.Write(" = document.all ? document.all[\"");
InBlock.gif             writer.Write(text1);
InBlock.gif             writer.Write("\"] : document.getElementById(\"");
InBlock.gif             writer.Write(text1);
InBlock.gif             writer.WriteLine("\");");
InBlock.gif             ListDictionary dictionary1 = (ListDictionary) entry1.Value;
InBlock.gif              foreach (DictionaryEntry entry2  in dictionary1)
ExpandedSubBlockStart.gif ContractedSubBlock.gif              dot.gif{
InBlock.gif                  writer.Write(text1);
InBlock.gif                  writer.Write(".");
InBlock.gif                  writer.Write(entry2.Key);
InBlock.gif                   if (entry2.Value ==  null)
ExpandedSubBlockStart.gif ContractedSubBlock.gif                   dot.gif{
InBlock.gif                      writer.WriteLine(" = null;");
InBlock.gif                       continue;
ExpandedSubBlockEnd.gif                  }
InBlock.gif                  writer.Write(" = \"");
InBlock.gif                  writer.Write(entry2.Value);
InBlock.gif                  writer.WriteLine("\";");
ExpandedSubBlockEnd.gif             }
ExpandedSubBlockEnd.gif         }
InBlock.gif         writer.Write("// -->\r\n</script>\r\n");
ExpandedSubBlockEnd.gif    }
ExpandedBlockEnd.gif}

     既然说M$实现得很草率,那么死结在哪里呢?死结就是这个Expando Attribute,什么是expando呢?Expando实际上是DHTML对象本身的一种特性的描述,就是说我们可以向DHTML对象动态的添加任意的属性和属性值,其实就类似一个hashtable。
 
     Expando在JScript中的使用,有两种方式。如果我们有: var obj = new Object(); 那么obj.xxx = 10; 和obj['xxx'] = 10; 所表现的效果是完全相同的。但是obj.xxx方式使用expando特性,只是JScript给我们的一个syntax sugar,实际上JScript解析引擎会自动把obj.xxx转换成obj['xxx']。而且obj[key]方式中的key,是任意的字符串或可转换为字符串的任意表达式。也就是说obj['0123456789'] = 10; obj['!@#$%^&*()'] = 10; obj['?><{}[]'] = 10; 都是合法的expando特性使用,只是他们不能写成obj.xxx这种形式。显然如果写成obj.xxx形式,obj.0123456789、 obj.!@#$%^&*()、obj.?><{}[],那么JScript的语法就全乱套了。
 
     知道了expando特型的实际意义,再来看RegisterExpandoAttribute()方法?是不是实现的很草率呢?这个方法不该使用"."运算符来访问expando属性,而应该使用"[]"运算符。
 
     BTW: 在JScript.NET中,expando作为一个修饰符出现,这时的具有expando特性的对象,只能使用"[]"运算符设置和访问expando属性了,并且分别表示不同属性值的obj.xxx还可以和obj.['xxx']共存于一个对象中。

本文转自博客园鸟食轩的博客,原文链接:http://www.cnblogs.com/birdshome/,如需转载请自行联系原博主。

目录
相关文章
|
2月前
|
监控 测试技术
当测试发现300个缺陷时
当测试发现300个缺陷时
13 0
|
2月前
|
设计模式 测试技术
什么是缺陷预防和缺陷改进?
什么是缺陷预防和缺陷改进?
|
3月前
|
测试技术 开发工具 数据安全/隐私保护
缺陷报告
缺陷报告
缺陷报告
|
8月前
|
程序员 测试技术 数据库
如何复现难以复现的缺陷
重现缺陷很容易陷入盲目的尝试,直到测试人员感到疲倦而放弃,也没有多少进展。提出错误猜测使得测试有明确的目标,在它的指引下测试人员可以自由发挥,而不会迷失方向。整个过程的特征是设定明确的目标、用实验去获得信息、根据新信息建立新目标。
106 0
|
8月前
|
程序员 测试技术 数据库
如何编写高质量的缺陷报告
本文介绍一些技巧和实践方法,来帮助测试人员编写高质量的缺陷报告。因为不同的项目团队对测试人员有不同的期望,读者在采纳这些基本实践时,需要做一些因地制宜的变化。
111 0
|
11月前
|
程序员
缺陷(bug)管理
理论上软件的缺陷是可修复的,不过有的修复成本比较高,不能追求软件的完美,根据风险来确定是否修复缺陷
|
测试技术
软件测试|产生缺陷的原因有哪些?如何归类缺陷?
软件测试|产生缺陷的原因有哪些?如何归类缺陷?
159 0
|
算法 计算机视觉
例举几种缺陷检测
例举几种缺陷检测
189 0
例举几种缺陷检测
|
运维 Cloud Native 测试技术
高质量的缺陷分析:让自己少写 bug
缺陷分析做得好,bug 写得少。阿里资深技术专家和你分享如何进行高质量的缺陷分析,总结了 5 个要点,通过缺陷分析消除开发中的各种盲点,打造一个学习型的团队。
高质量的缺陷分析:让自己少写 bug
|
存储 容器 程序员