RegisterExpandoAttribute()实现缺陷

简介:

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

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

 ClientScriptManager.RegisterExpandoAttribute (String, String, String)    
 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控件,使用:
  this.ClientScript.RegisterExpandoAttribute("lblTest", "message", "ok.");
  this.ClientScript.RegisterExpandoAttribute("lblTest", "resulte", "'string'");
  this.ClientScript.RegisterExpandoAttribute("lblTest", "resulte", "'string'",  false);

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

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

     既然说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/,如需转载请自行联系原博主。

目录
相关文章
|
Prometheus Cloud Native Go
Go 1.22 标准库 slices 新增函数和一些旧函数增加新特性
Go 1.22 标准库 slices 新增函数和一些旧函数增加新特性
|
10月前
|
机器学习/深度学习 人工智能 供应链
2024年的供应链回顾与2025展望:数字化转型与韧性提升
2024年的供应链回顾与2025展望:数字化转型与韧性提升
|
存储 人工智能 自然语言处理
阿里云Elasticsearch AI场景语义搜索最佳实践
本文介绍了如何使用阿里云Elasticsearch结合搜索开发工作台搭建AI语义搜索。
17902 68
|
缓存 Ubuntu 网络协议
ubuntu ifconfig命令找不到
通过上述指导,无论你是面临 `ifconfig`命令缺失的困惑,还是希望深入了解Ubuntu系统下的网络管理技巧,都能找到针对性的解决方案,进一步提升你的系统管理能力。
544 2
|
JavaScript API 开发者
Vue3自定义hooks
Vue3自定义hooks
233 0
BurpSuite2021 -- 抓包使用及设置
BurpSuite2021 -- 抓包使用及设置
414 1
|
传感器 人工智能 安全
AI识别技术在智慧工地的应用场景
智慧工地是指以物联网、移动互联网技术为基础,充分应用人工智能等信息技术,通过AI赋能建筑行业,对住建项目内人员、车辆、安全、设备、材料等进行智能化管理,实现工地现场生产作业协调、智能处理和科学管理。AI智能分析系统,对工地未佩戴安全帽、未穿反光背心、明烟明火等违规现象实时识别报警,可灵活对接智慧工地管理平台系统,为政府部门、施工单位和监管企业提供高效、经济、安全的安监方案,推动施工作业风险管理从事后管理向事前、事中管理转变,使作业风险得到有效管控。
999 1
|
前端开发
antd-protable的分页逻辑封装
antd-protable的分页逻辑封装
783 0
|
机器学习/深度学习 存储 达摩院
Python动物图像分割API简单调用实例演示,阿里达摩院视觉智能开放平台使用步骤
图像分割的目标是将图像中的像素分成不同的组或区域,使具有相似特征的像素属于同一组,从而实现目标对象的提取。常见的图像分割方法之一是语义分割(Semantic Segmentation)。 语义分割通过深度学习模型,如卷积神经网络(CNN),学习图像的特征表示,并生成像素级的分割结果。通常,语义分割使用全卷积网络(FCN)或其改进版本作为网络结构。编码器用于提取图像的特征表示,而解码器通过上采样操作将特征图还原到原始图像的尺寸,并生成分割结果。
630 0
|
人工智能 数据挖掘 Go
即插即用! | 国防科大联合慕尼黑工业大学提出新型解耦头 TSCODE: 助力目标检测器轻松涨点!
即插即用! | 国防科大联合慕尼黑工业大学提出新型解耦头 TSCODE: 助力目标检测器轻松涨点!
508 0
即插即用! | 国防科大联合慕尼黑工业大学提出新型解耦头 TSCODE: 助力目标检测器轻松涨点!