ASPNET编程经常会碰到在前台页面代码中要使用(或绑定)后台程序中变量值的问题一般有<%=str%>和<%#str%>两种方式这里简单总结一下如有错误或异议之处敬请各位指教
一方面这里所讲的前台即通常的aspx文件后台指的是与aspx相关联的CodeBehind文件后缀名为aspxcs另一方面这里的绑定是指用户发出访问某一页面指令后服务器端在执行过程中就已经将前台代码进行了赋值而后生成html格式回传客户端显示而并非已经显示到客户端后然后通过其他方法(如ajax)去服务器端获取相应变量
备注上面说的两个文件是常见的代码隐藏(codebehind)模式还有一种是代码嵌入(codebesideinline)模式那就是只存在aspx一个文件而后台代码则写入此文件的<scripttype="text/javascript"runat="server"></script>之中(还有一些语法上区别)这对于本文讨论的问题略有影响因为代码嵌入是声明性代码与C#/VBNET代码都一起编译到一个类里面而代码隐藏则将声明性代码与C#/VBNET代码分开几次进行翻译/编译因此前者是局部与局部(partial)的关系后者基类与派生类的关系但这仅仅影响所能绑定变量的范围(与修饰符有关)下面会提到以下均以代码隐藏模式为例
一般来说在前台代码的三种位置可能会用到(绑定)后台变量
服务器端控件属性或HTML标签属性
JavaScript代码中
Html显示内容的位置(也就是开始标签与结束标签之间的内容如<div>这里</div>(Html标签)或者<asp:LabelID="Label"runat="server"Text="Label">这里</asp:Label>(服务器端控件)它作为占位符把变量显示于符号出现的位置)
对于第一种位置有一些约束条件
()一般的属性要求是字符串型或数值型(下面会提到有些服务器端属性支持属性为数据集合)
()并不是所有的属性都可以绑定变量有些属性例如runat属性必须是"server"常量即使绑定的字符串是server也会导致分析器分析时出错
()有一种属性他要求属性值有约束(类型约束比如服务器端控件要求TabIndex属性是short类型或者字符串内容有约束)也应该在绑定时满足否则依然可能编译时报错
()还一种属性虽然属性本身有约束但即使绑定的变量不满足约束也可以编译通过比如input的checked属性它只有checked字符串是合法的但如果通过绑定获取到的字符串不是checked那么这些属性将有自己内部处理机制来保证可以正常使用
()还要注意即使对于同一类属性服务器端和HTML的属性的处理机制也不同同样是TabIndex(tabIndex)前者如果不满足则分析器错误后者则忽略这一问题
对于第二种位置一般只要绑定的后台变量和JavaScript中数据类型兼容即可
对于第三种位置如果绑定出现的位置不在服务器端控件内部则没有约束条件只要是常量字符串可以出现的位置均可以绑定但是对于置于服务器端控件内部也就是上面那种<asp:LabelID="Label"runat="server"Text="Label">这里</asp:Label>的方式则有约束条件通过总结归纳为四类服务器端控件如果绑定的代码出现在这些控件的开始和结束标签之间(这里所说的控件是指如果绑定代码外有多层的嵌套控件包围则是指包围绑定代码的最内层控件)有不同的显示结果
()约束型控件这类控件要求它的开始标签和结束标签中只能包含指定的子控件因此如果在这里出现代码块将编译错误例如
<asp:DataListrunat="server"></asp:DataList>在它之间要求必须嵌套<ItemTemplate></ItemTemplate>
()非嵌套类控件这类控件不允许在内部嵌套其他控件或标签只能是常量字符串它会将开始标签和结束标签中常量字符串内容作为他的属性例如上面提到的TextBox它会将标签间内容作为它的Text属性值
()嵌套类控件这类控件可以嵌套其他任意控件也可以包含字符串因此可以正常显示绑定代码块所表示的字符串内容例如Label控件Panel等
()数据绑定类控件这类控件是ASPNET提供的服务器端控件除了可以绑定普通的变量类型也可以绑定一个数据集合(只能采取下面的第二种方式实现)
关于是否加引号在以上三个位置使用时是否应该将<%=str%>或<%#str%>置于单引号或双引号中呢?对于在不同位置处理的方式是不同的(具体请在下面两种方式的具体介绍时加以体会)
()对于第一种位置由于JavaScript是弱类型的如果绑定时加引号显然就认为就当做字符串来处理这始终是正确的如果绑定时不加引号它将认为这是个数值型的那么如果获取的真是数值当然可以如果是非数值型则将产生脚本错误这即使对于JavaScript赋值常量时也是同样的
以下为引用的内容
vartest=b;//运行时报错
vartest=;//正确是数值型
vartest="b";//正确字符串型
()对于第二种位置经过测试无论是对于服务器端控件属性还是HTML标签属性加引号总是正确的如果不加引号则两种属性的处理方式不同
对于服务器端控件属性如果绑定的代码块不加引号则编译时会提示“验证(ASPNET)特性值前后必须加引号”的警告信息但是生成为HTML后对应生成的HTML属性已经被加上引号并获取了正确的绑定结果因此加不加引号不会影响使用但是建议对于规范的代码还是加上为好
对于HTML标签属性如果不加引号则编译时会提示“验证(XHTMLTransitional):特性值前后必须加引号”的警告信息并且生成为HTML属性也确实没有加上引号那么虽然属性后面确实是没有加上引号的正确的绑定值但是不一定能展示出想要看到的结果比如对于input标签的value属性如果绑定的字符串是"helloworldfromvariable”则在客户端的input显示出的内容实际上只是"hello”字符串生效的属性值是一个被截断的字符串它从属性后的一串字符串(若未加引号)的第一个非空字符开始截止到下一个空字符的前一个字符为止(比如对于"helloworld”结果将是"hello”)因此加上引号是必须的
()对于第三种位置加与不加引号获取的值及其显示均不受影响
因此建议所有绑定表达式都加上引号作为字符串获取然后根据实际需求用相应函数进行转换得到所需要的类型
另外这里所说的后台变量是泛指的包括如下
成员变量
方法或属性的返回值
表达式也就是所有后台能够执行的代码运行后所得到的值(也就是直接将后台代码写在前台代码中记得使用完全限定名或在后台中using相关namespace)
数据集合
后台变量有一些约束条件需要满足
()变量修饰符要求变量是静态或者实例字段均可对于代码隐藏模式的ASPNET以上的所述的变量必须为public或protected类型(因为是基类与派生类的关系)private或者internal都不行而代码嵌入模式则任何修饰符的变量均可访问(一个类内部的关系)
()变量类型要求由于前台属性一般是字符串类型而JavaScript基本类型也就是字符串型数字型布尔型因此对应的变量应该也是这几种方式其余类型如果不被支持(如复杂类型数组引用类型等)前台获取的就是调用了变量的ToString()方法所得到的字符串因此在绑定时要根据情况看是否能进行隐式类型转换必要时还要用相关函数来强制转换以保证前台可以获得正确的值当然对于数据绑定类控件它的有些属性可以为数据集合但这时的绑定只能通过下面第二种方式才被支持
以上是一些概念和基本约束这些都是两种方式都应该满足的下面具体介绍两种方式来实现前台代码中(以下称为代码块)绑定后台变量的功能