在迁移一个基于.NET Framework1.1的应用程序到新服务器的过程中,遇到了一个关于验证器的问题。这个问题涉及到验证器如何渲染客户端验证所需的数据。
在.NET Framework 1.1.4中,所有数据都是通过属性渲染的,因此必须遵循属性命名约定。
在.NET Framework 2.0或更高版本中,大部分所需数据是通过Expando属性渲染的。这意味着创建了一个JavaScript对象来承载所需的数据。
乍一看,这似乎只是存储方式的不同,但实际上隐藏了一个与HTML属性和JavaScript变量命名约定差异相关的问题。
在迁移一个旧的.Text v0.91应用程序到没有安装.NET Framework1.1的新服务器时,发现所有带有验证器的页面都引发了JavaScript错误。
var ctl00_pageBody-2_RequiredFieldValidator1 =
document.all ? document.all["ctl00_pageBody-2_RequiredFieldValidator1"] :
document.getElementById("ctl00_pageBody-2_RequiredFieldValidator1");
问题显而易见,字符‘-’是JavaScript操作符,不能在变量名中使用。JavaScript解析器在找到‘-’后期望在‘ctl00_pageBody’后面有一个‘;’。
正如之前提到的,在.NET Framework1.1中,这个对象并不存在,所有数据都是作为属性简单渲染的。
有两种方法可以解决这个问题:可以强制验证器渲染属性,或者更改ID值以去除不需要的字符。
验证器控件已经准备好在旧模式下工作,但要启用该模式,需要更改应用程序的所有行为。可以通过添加以下web.config数据来实现这一点:
<system.web>
<xhtmlConformance mode="Legacy" />
</system.web>
虽然这是最喜欢的解决方案,但选择了另一种方法,因为不确定潜在的副作用,需要进行微创手术式的更改,以最小化影响。
这种方法要求您更改验证器层次结构中所有控件的ID,以防止JavaScript命名问题。这可能需要一些时间,但通常应该没有问题。
但在案例中并非如此。花了很长时间才找到pageBody-2控件。最终发现它是一个动态加载的UserControl,其ID也是动态组成的。不幸的是,这一切都是在内部基类的私有方法中完成的,唯一的实用解决方案是重写Page Render方法,并将模式‘_pageBody-’替换为‘_pageBody_’。