Chia° bocom 第5章脚本运行期库对象 前面章节已经介绍了ASP如何使用在服务器上定义的对象的实例,并充分利用所提供的 方法和属性扩展ASP的性能。有一系列的对象可供使用,包括脚本对象和标准IS/ASP安装的 组件,以及自己创建的或者从其他供应商处购买的对象。也可以在互联网从各种网站免费下 载对象,并在自己的页面上使用。 这一章将讨论由ASP脚本环境提供的一般称为“脚本运行期库”( Scripting Runtime Library)的对象。这些对象通过正在使用的脚本引擎提供给代码,与ASP脚本程序一起完成多 种实用任务。 还有一种组件是“活动服务器组件”( Active Server Component),通过单独的 ActiveX DLL文件或者其他文件来实现。后面章节将讨论相关内容。 当然,需要研究如何在页面上使用这些对象。在前一章中,我们已经了解了服务器如何 提供一个方法来实例化对象,本章将深入讨论这个内容 本章将介绍以下内容: 脚本引擎以脚本对象方式提供了什么 如何创建脚本对象及其他组件实例。 脚本对象的成员和属性概要 ·如何在代码中使用脚本对象 下面开始研究脚本对象的定义 5.1脚本对象的定义 前面章节研究了ASP对象模型。 对象模型是用来理解系统的各个部分相互关系的一种基本手段 ASP对象模型提供了一种结构,用来作为一个整体操纵HTTP请求、响应及ASP环境中的 不同元素。例如,我们已经看到,如何通过查看ASP请求对象的 cookie集合,得到来自浏览器 的任何 cookie值 我们使用的脚本语言也有对象模型。然而,脚本语言提供的这一对象模型,不同于由 ASP DLL直接提供的对象模型,脚本对象是由 Microsoft脚本运行期库( scrum.d)提供的,安 装缺省的 Active Scripting脚本引擎时,也安裝了 Microsof脚本运行期库 5.1.1不同类型的对象和组件 不要对“对象”和“组件”这两个名词感到困惑,在一定范围内它们都可以作为ASP的 一部分,同样可以通过COM对其进行访问。从概念上可以将它们分为四类 ASP内置对象,如 Object Context、 Request、 Response、 Application、 Session、 Server 和 ASPError。本书的第2章到第4章已经研究了这些内容
下载 第5章 脚本运行期库对象 前面章节已经介绍了 A S P如何使用在服务器上定义的对象的实例,并充分利用所提供的 方法和属性扩展A S P的性能。有一系列的对象可供使用,包括脚本对象和标准 I I S / A S P安装的 组件,以及自己创建的或者从其他供应商处购买的对象。也可以在互联网从各种网站免费下 载对象,并在自己的页面上使用。 这一章将讨论由 A S P脚本环境提供的一般称为“脚本运行期库” (Scripting Runtime L i b r a r y )的对象。这些对象通过正在使用的脚本引擎提供给代码,与 A S P脚本程序一起完成多 种实用任务。 还有一种组件是“活动服务器组件” (Active Server Component),通过单独的 A c t i v e X D L L文件或者其他文件来实现。后面章节将讨论相关内容。 当然,需要研究如何在页面上使用这些对象。在前一章中,我们已经了解了服务器如何 提供一个方法来实例化对象,本章将深入讨论这个内容。 本章将介绍以下内容: • 脚本引擎以脚本对象方式提供了什么。 • 如何创建脚本对象及其他组件实例。 • 脚本对象的成员和属性概要。 • 如何在代码中使用脚本对象。 下面开始研究脚本对象的定义。 5.1 脚本对象的定义 前面章节研究了A S P对象模型。 对象模型是用来理解系统的各个部分相互关系的一种基本手段。 A S P对象模型提供了一种结构,用来作为一个整体操纵 H T T P请求、响应及A S P环境中的 不同元素。例如,我们已经看到,如何通过查看 A S P请求对象的c o o k i e集合,得到来自浏览器 的任何c o o k i e值。 我们使用的脚本语言也有对象模型。然而,脚本语言提供的这一对象模型,不同于由 ASP DLL直接提供的对象模型,脚本对象是由 M i c r o s o f t脚本运行期库( s c r r u n . d l l )提供的,安 装缺省的Active Scripting脚本引擎时,也安装了M i c r o s o f t脚本运行期库。 5.1.1 不同类型的对象和组件 不要对“对象”和“组件”这两个名词感到困惑,在一定范围内它们都可以作为 A S P的 一部分,同样可以通过C O M对其进行访问。从概念上可以将它们分为四类: • A S P内置对象,如 O b j e c t C o n t e x t、R e q u e s t、R e s p o n s e、A p p l i c a t i o n、S e s s i o n、S e r v e r 和A S P E r r o r。本书的第2章到第4章已经研究了这些内容
第5章脚本运行期对象135 下载 ·脚本对象。通过脚本运行期库使用,如 Dictionary、 FileSystem和 extReam。这是本章 要讨论的对象。 ·可安装的组件。由 Microsoft在IS50和ASP30标准安装时提供。这将在下一章讨论。 其他组件。从其他独立厂商购买的、在网站上发现的或者自己创建的组件。还有一些其 他的由 Windows服务或产品提供的组件,如 Windows Scripting Host。在本书的附录中提 供了相应的列表,本书专门有一部分章节讲述如何构建自己的组件。 512 VBScript和 SCrip脚本对象 作为脚本运行期库的一部分, Microsof提供三个主要的对象 Dictionary对象提供一个极为有用的存储对象,它用来存储值,通过对象的名字而不是 其索引进行访问和引用。例如,对于存储从 ASP Request对象中检索到的名称/值对,这 是非常合适的。 FileSystemObject对象提供了对服务器底层文件系统的访问(在客户端上使用IE5.0,与名 为“ Hypertext Application(HTA)”的特殊类型的页面协同使用)。可用 FileSystemObject 对象遍历计算机的本地及网络的驱动器、文件夹和文件。 TextStream对象提供对存储在磁盘上文件的访问,用于同 FileSystemObject对象协同使用 TextStream对象能够读出或写入文本(顺序的)文件,并仅能通过 FileSystemObject对象进 行实例化,所以人们常常认为 TextStream对象是 FileSystemObject对象的子对象 FileSystemobject对象是其他一系列用来与文件系统交互的对象和集合的“父代”。该对 象提供了对象的三个集合: Drives、 Folders和 Files集合,每个集合分别是相应的 Drive Folder和File对象的集合。它们用来进行磁盘上的驱动器、文件夹(目录)和文件的遍历和定位。 对象间的关系如图5-1所示。 脚本运行期 FileSystemObject对象 Textstream对象 Dictionary对象 Drive对象 Folders集合 Folder对象 les集合 Fle对象 图5-1脚本运行期库中对象间关系 下面,将依次介绍这些对象和集合,以及如何使用它们。然而,首先要理解对象实例与 组件的创建或实例化方式之间的差异。这是下一节的主要内容
• 脚本对象。通过脚本运行期库使用,如 D i c t i o n a r y、F i l e S y s t e m和Te x t S t r e a m。这是本章 要讨论的对象。 • 可安装的组件。由M i c r o s o f t在IIS 5.0和ASP 3.0.标准安装时提供。这将在下一章讨论。 • 其他组件。从其他独立厂商购买的、在网站上发现的或者自己创建的组件。还有一些其 他的由Wi n d o w s服务或产品提供的组件,如 Windows Scripting Host。在本书的附录中提 供了相应的列表,本书专门有一部分章节讲述如何构建自己的组件。 5.1.2 VBScript和J S c r i p t脚本对象 作为脚本运行期库的一部分, M i c r o s o f t提供三个主要的对象: • D i c t i o n a r y对象提供一个极为有用的存储对象,它用来存储值,通过对象的名字而不是 其索引进行访问和引用。例如,对于存储从 ASP Request对象中检索到的名称 /值对,这 是非常合适的。 • F i l e S y s t e m O b j e c t对象提供了对服务器底层文件系统的访问 (在客户端上使用I E 5 . 0,与名 为“Hypertext Application(HTA )”的特殊类型的页面协同使用 )。可用F i l e S y s t e m O b j e c t 对象遍历计算机的本地及网络的驱动器、文件夹和文件。 • Te x t S t r e a m对象提供对存储在磁盘上文件的访问,用于同F i l e S y s t e m O b j e c t对象协同使用。 Te x t S t r e a m对象能够读出或写入文本 (顺序的)文件,并仅能通过F i l e S y s t e m O b j e c t对象进 行实例化,所以人们常常认为 Te x t S t r e a m对象是F i l e S y s t e m O b j e c t对象的子对象。 F i l e S y s t e m O b j e c t对象是其他一系列用来与文件系统交互的对象和集合的“父代”。该对 象提供了对象的三个集合: D r i v e s、F o l d e r s和F i l e s集合,每个集合分别是相应的 D r i v e、 F o l d e r和F i l e对象的集合。它们用来进行磁盘上的驱动器、文件夹 (目录)和文件的遍历和定位。 对象间的关系如图5 - 1所示。 图5-1 脚本运行期库中对象间关系 下面,将依次介绍这些对象和集合,以及如何使用它们。然而,首先要理解对象实例与 组件的创建或实例化方式之间的差异。这是下一节的主要内容。 第5章 脚本运行期库对象计计135 下载 Drive对象 FileSystemObject对象 脚本运行期 TextStream对象 Drives集合 Dictionary对象 Folders集合 Files集合 Folder对象 File对象
136Ap3高编程 Chinapub coM 下载 52创建对象和组件实例 创建脚本运行期库对象的实例与创建任何其他对象和组件的实例化方式完全相同。可使 用 ASP Server对象提供的 CreateObject方法(确保对象创建在当前页面的环境内),或者使用 个元素。我们将研究这两种方法,究竟采用那种方法依赖于页面的需要。 521使用 Server CreateObject方法 正如在研究 Server对象的时候看到的,组件或其他对象实例可根据它们的PogD来创建: Dim objThis Set objThis Server Createobject("ADODB Connection) ProgId字符串“正式的”格式是“供应商组件版本”,供应商的名字和版本是可选的。 通常 ProgId只包含前两部分(如上例)。少数供应商在 ProgID中设置版本编号,这将避免向后兼 容的新版本使用同样的 ProgId,这要求改变ASP页面才能使用新版本。 522使用元素 可以使用标准的HTML元素通过增加 RUNAT参数并指定其值为“SERⅤER” 来在服务器上创建一个组件实例。另外,通常是提供对象的 Pronged字符串而不是数字的 ClassID OBUECT ID='o RUNAT="SERVER" PROGI object> PARAM NAM VALUE="value1'> 元素内可通过 元素进行设置,就像通常在HTML页面中所做的一样。在APS中使用元 素时不要求 CODEBASE属性,当其不可用时,服务器不会试图下载以及安装对象或对象。 1.指定一个 ClassID 另外,可以指定想要创建的对象或组件的 ClassID。在不知道目标机安装了什么其他组件 的情况下,这是非常有用的。例如在客户端上的浏览器的页面上实例化组件时。 在理论上,组件的 ProgID(文本“供应商组件”)不应该相互冲突,应该是唯一的。然而, 这不是无懈可击的。有可能美国北方的一个供应商与希腊小岛上的一个供应商同名。但是, 使用 ClassID识别访问时,因为 ClassID是唯一的,同名情况就不会发生。 如果决定使用对象或组件的 ClassID,应将其放入 CLASSID属性中,而不是 PROGID属性 CLASSID='clsie A7-E0F9-11D2-B2E9-00105A42AF30 AM NAME="paramI 但在自己的服务器上实例化对象时,应该知道对象和组件的安装方式。这样在ASP代码
5.2 创建对象和组件实例 创建脚本运行期库对象的实例与创建任何其他对象和组件的实例化方式完全相同。可使 用ASP Server对象提供的C r e a t e O b j e c t方法(确保对象创建在当前页面的环境内 ),或者使用一 个元素。我们将研究这两种方法,究竟采用那种方法依赖于页面的需要。 5.2.1 使用S e r v e r. C r e a t e O b j e c t方法 正如在研究S e r v e r对象的时候看到的,组件或其他对象实例可根据它们的 P r o g I D来创建: P r o g I D字符串“正式的”格式是“供应商 .组件.版本”,供应商的名字和版本是可选的。 通常P r o g I D只包含前两部分(如上例)。少数供应商在P r o g I D中设置版本编号,这将避免向后兼 容的新版本使用同样的P r o g I D,这要求改变A S P页面才能使用新版本。 5.2.2 使用元素 可以使用标准的 H T M L 元素通过增加 R U N AT参数并指定其值为“ S E RV E R” 来在服务器上创建一个组件实例。另外,通常是提供对象的 P r o n g I D字符串而不是数字的 C l a s s I D: 如果上面脚本的对象有相应的属性可在脚本中使用,在 元素内可通过 元素进行设置,就像通常在 H T M L页面中所做的一样。在 A P S中使用元 素时不要求C O D E B A S E属性,当其不可用时,服务器不会试图下载以及安装对象或对象。 1. 指定一个C l a s s I D 另外,可以指定想要创建的对象或组件的 C I a s s I D。在不知道目标机安装了什么其他组件 的情况下,这是非常有用的。例如在客户端上的浏览器的页面上实例化组件时。 在理论上,组件的P r o g I D (文本“供应商.组件”)不应该相互冲突,应该是唯一的。然而, 这不是无懈可击的。有可能美国北方的一个供应商与希腊小岛上的一个供应商同名。但是, 使用C l a s s I D识别访问时,因为C l a s s I D是唯一的,同名情况就不会发生。 如果决定使用对象或组件的 C l a s s I D,应将其放入C L A S S I D属性中,而不是P R O G I D属性。 如: 但在自己的服务器上实例化对象时,应该知道对象和组件的安装方式。这样在 A S P代码 136计计ASP 3 高级编程 下载
hinapub.com 第5章脚本运行期库对象 137 下载 中创建对象实例时,可以安全地使用 Pronged。这就是 ClassID很少在ASP页面内使用的原因 然而,因为PogD用于查找 CLSID,如果愿意也可以用组件或对象的CasD代替PgID 2.设置对象实例的作用域 缺省情况下,所有在ASP页面中创建的对象与组件实例(无论用 Server CreateObject方法或 元素)都有页面内的作用域( page scope)。这意味着,对象与组件只有该页在ASP上 运行时才存在,当页面完成并且把结果发送到客户端以后就自动地取消了 然而,如果在 global.asa文件(它存在于站点或虚拟应用程序的根目录)中放置声 明,可以将对象或组件的作用域指定为应用程序或会话作用域。 (1)在应用程序层作用域创建对象 通过设置 SCOPE属性为“ APPLICATI 创建应用程序层作用域对象 /OBJECT> 应用程序开始时就创建了对象实例,即一旦用户从虚拟应用程序的目录请求一个页面 就创建对象实例。对于缺省Web站点,这可以是站点上的任一目录。直到应用程序结束(最后 的用户会话结束)前,对象实例一直存在,并且可以被虚拟应用程序或站点目录内任一页面内 的任意用户引用和使用。 (2)在会话层作用域创建对象 如果想创建由单个用户使用的对象实例,其作用域为他访问的所有页面,可创建会话层 作用域对象。这通过将 SCOPE属性设置为“ SESSION”来实现: 对象一旦被引用就被创建,引用是由用户从虚拟应用程序或站点载入的页面内的程序代 码完成的(在 global asa文件中有声明)。当用户会话生命周期结束并被取消时,它引 用的对象实例也就取消了。 (3)关于作用域和状态 使对象实例的作用域为全局的或者为用户会话全局环境看起来是一个好主意,但在实际使 用时有些问题需要考虑,其中之一是在用户的许多请求之间能够有效地保护对象的状态 句话说,可以设定对象的一些属性,它们对使用的所有页面是共用的。因为不必每次都创建 新的实例并设置其属性,所以这看起来是个较好的办法 事实上,微软建议一般情况下不要这样做,这一思想是传统程序设计思想的残余。在 Web上,要面对的最大问题是服务器以及Web应用程序及所提供的动态网页如何应付数以百万 计的网站访问者。将组件实例驻留在内存中等待一个特定用户的页面请求,对可能有几百个 用户同时浏览的网站来说,这样做不能有效地使用资源 Window2000提供新的COM+运行期特性,它能够处理组件的创建、缓存和使用,采用 种吞吐量最大化但所占服务器资源最小化的方式。对象实例存储在哪里和存储多久的问题, 最好由操作系统自己完成,而不是由程序员决定 也就是说,在页面内需要的地方创建对象实例,当页面终止时让其消失。COM+整理这 碎片,自动处理后台的一些复杂工作。如果要了解有关这方面的内容,第14章比较详细地
中创建对象实例时,可以安全地使用 P r o n g I D。这就是C l a s s I D很少在A S P页面内使用的原因。 然而,因为P r o g I D用于查找C L S I D,如果愿意也可以用组件或对象的 C l a s s I D代替P r o g I D。 2. 设置对象实例的作用域 缺省情况下,所有在 A S P页面中创建的对象与组件实例 (无论用S e r v e r. C r e a t e O b j e c t方法或 元素)都有页面内的作用域(page scope)。这意味着,对象与组件只有该页在 A S P上 运行时才存在,当页面完成并且把结果发送到客户端以后就自动地取消了。 然而,如果在g l o b a l . a s a文件(它存在于站点或虚拟应用程序的根目录 )中放置声 明,可以将对象或组件的作用域指定为应用程序或会话作用域。 (1) 在应用程序层作用域创建对象 通过设置S C O P E属性为“A P P L I C AT I O N”, 创建应用程序层作用域对象: 应用程序开始时就创建了对象实例,即一旦用户从虚拟应用程序的目录请求一个页面, 就创建对象实例。对于缺省W e b站点,这可以是站点上的任一目录。直到应用程序结束 (最后 的用户会话结束)前,对象实例一直存在,并且可以被虚拟应用程序或站点目录内任一页面内 的任意用户引用和使用。 (2) 在会话层作用域创建对象 如果想创建由单个用户使用的对象实例,其作用域为他访问的所有页面,可创建会话层 作用域对象。这通过将S C O P E属性设置为“S E S S I O N”来实现: 对象一旦被引用就被创建,引用是由用户从虚拟应用程序或站点载入的页面内的程序代 码完成的(在g l o b a l . a s a文件中有声明)。当用户会话生命周期结束并被取消时,它引 用的对象实例也就取消了。 (3) 关于作用域和状态 使对象实例的作用域为全局的或者为用户会话全局环境看起来是一个好主意 ,但在实际使 用时有些问题需要考虑,其中之一是在用户的许多请求之间能够有效地保护对象的状态。换 句话说,可以设定对象的一些属性,它们对使用的所有页面是共用的。因为不必每次都创建 新的实例并设置其属性,所以这看起来是个较好的办法。 事实上,微软建议一般情况下不要这样做,这一思想是传统程序设计思想的残余。在 We b上,要面对的最大问题是服务器以及 We b应用程序及所提供的动态网页如何应付数以百万 计的网站访问者。将组件实例驻留在内存中等待一个特定用户的页面请求,对可能有几百个 用户同时浏览的网站来说,这样做不能有效地使用资源。 Window 2000提供新的C O M +运行期特性,它能够处理组件的创建、缓存和使用,采用一 种吞吐量最大化但所占服务器资源最小化的方式。对象实例存储在哪里和存储多久的问题, 最好由操作系统自己完成,而不是由程序员决定。 也就是说,在页面内需要的地方创建对象实例,当页面终止时让其消失。 C O M +整理这 些碎片,自动处理后台的一些复杂工作。如果要了解有关这方面的内容,第 1 4章比较详细地 第5章 脚本运行期库对象计计137 下载
138:3商程 研究了组件的创建。 当然,在某种情况下,我们可能要求一个对象具有应用程序层和会话层的作用域,尤其 是在页面请求间保存状态时。在后面讨论 Dictionary对象时,将有一个这方面的实例 5.23 Server CreateObject与的区别 Server CreateObject方法立即创建一个对象实例。在大多数情况下这也是我们所希望的。 而元素只有首次引用一个对象时才创建指定的对象实例。因此如果在代码中停止 使用该对象,则不创建该对象实例。 如果代码只在某种情况下使用这个对象(可能依赖于请求参数的值),这也许是有用的。因 为如果不需要这个对象,则可以节省服务器的资源。 然而,如果肯定需要创建某一对象,可使用 Server CreateObject方法完成。用 元素创建对象有助于防止在代码中取消对对象的调用时,忘记取消程序中的 Server. CreateObject行,当然这是一个粗心的程序设计。 最后需要记住的是,如果对象是使用 Server Createobject方法创建的,就可以从会话或应 用程序中去掉对象,但使用元素创建的,则不行。 524组件线程模型 在页面内使用对象或组件时,应该考虑的另一个问题是该对象涉及到的响应多个请求的 行为方式。事实上在ASP里,这是所需要理解的最复杂的题目之一。一个组件的线程模型, 结合其作用域,影响该组件和应用程序的性能和效率,也影响将它实例化的ASP页面 线程就是由处理器执行的系统对象,用于完成由组件代码定义的任务。每一个 线程都可以被认为是单个二进制指令集。在像 Windows这样的多线程环境中,多个线 程可同时运行。 实际上有五个线程模型(包括在 Windows2000里引入的 Neutral- threading模型) Single-threaded(单线程):某一时刻只能有一个进程使用某组件 Apartment-threaded(单元线程):若干进程都可以使用某组件,但只有一个在指定的线 程上。 Neutral- threaded(中立线程):若干进程都能使用某组件,并且可以使用指定的一组线程 中的任何一个。 Multiple- threaded或Free- threaded(多线程或自由线程):若干进程都能使用某组件,并且 这些进程可以运行在不同的线程上。 Both- -threaded(双线程):对象既可以是单元线程的又可以作为自由线程的 在这里不解释线程模型的技术细节,本书后面有相应的内容 单元线程的组件(例如使用 Visual basic创建的或作为XML脚本的组件)可在页面层作用域 内很好地运行,在会话层作用域内也是可以接受的。事实上,在页面层,由于较低的数据处 理开销,也能很好地运行双线程的组件 Windows2000中的中立线程的模型甚至提供了更好的性能,尽管到目前为止只有很少的 这样的组件和与之相适应的开发工具
研究了组件的创建。 当然,在某种情况下,我们可能要求一个对象具有应用程序层和会话层的作用域,尤其 是在页面请求间保存状态时。在后面讨论 D i c t i o n a r y对象时,将有一个这方面的实例。 5.2.3 Server. C r e a t e O b j e c t与的区别 S e r v e r. C r e a t e O b j e c t方法立即创建一个对象实例。在大多数情况下这也是我们所希望的。 而元素只有首次引用一个对象时才创建指定的对象实例。因此如果在代码中停止 使用该对象,则不创建该对象实例。 如果代码只在某种情况下使用这个对象 (可能依赖于请求参数的值 ),这也许是有用的。因 为如果不需要这个对象,则可以节省服务器的资源。 然而,如果肯定需要创建某一对象,可使用 S e r v e r. C r e a t e O b j e c t方法完成。用 元 素 创 建 对 象 有 助 于 防 止 在 代 码 中 取 消 对 对 象 的 调 用 时 , 忘 记 取 消 程 序 中 的 S e r v e r. C r e a t e O b j e c t行,当然这是一个粗心的程序设计。 最后需要记住的是,如果对象是使用 S e r v e r. C r e a t e o b j e c t方法创建的,就可以从会话或应 用程序中去掉对象,但使用 元素创建的,则不行。 5.2.4 组件线程模型 在页面内使用对象或组件时,应该考虑的另一个问题是该对象涉及到的响应多个请求的 行为方式。事实上在 A S P里,这是所需要理解的最复杂的题目之一。一个组件的线程模型, 结合其作用域,影响该组件和应用程序的性能和效率,也影响将它实例化的 A S P页面。 线程就是由处理器执行的系统对象,用于完成由组件代码定义的任务。每一个 线程都可以被认为是单个二进制指令集。在像 Wi n d o w s这样的多线程环境中,多个线 程可同时运行。 实际上有五个线程模型 (包括在Windows 2000里引入的N e u t r a l - t h r e a d i n g模型): • Single-threaded(单线程):某一时刻只能有一个进程使用某组件。 • Apartment-threaded (单元线程):若干进程都可以使用某组件,但只有一个在指定的线 程上。 • N e u t r a l - t h r e a d e d (中立线程):若干进程都能使用某组件,并且可以使用指定的一组线程 中的任何一个。 • M u l t i p l e - t h r e a d e d或Free-threaded (多线程或自由线程):若干进程都能使用某组件,并且 这些进程可以运行在不同的线程上。 • Both-threaded(双线程):对象既可以是单元线程的又可以作为自由线程的。 在这里不解释线程模型的技术细节,本书后面有相应的内容。 单元线程的组件(例如使用Visual Basic创建的或作为X M L脚本的组件)可在页面层作用域 内很好地运行,在会话层作用域内也是可以接受的。事实上,在页面层,由于较低的数据处 理开销,也能很好地运行双线程的组件。 Windows 2000中的中立线程的模型甚至提供了更好的性能,尽管到目前为止只有很少的 这样的组件和与之相适应的开发工具。 138计计ASP 3 高级编程 下载
chinaopub.com 第5章脚本运行期对象139 下载 如果需要会话层组件,使用可用的双线程的组件。并且如果需要应用程序层作用域,可 直使用双线程的组件 然而,微软建议避免使用会话层作用域的组件,甚至不使用应用程序层作用域的组件, 除非这些组件是绝对需要的。使组件的活动时间超过作用域为页面级的组件所要求的时间, 对于由COM+提供代理特性的对象是没有益处的。 525引用对象类型库 在早先的ASP版本中,在脚本中使用对象或组件时,组件内定义的公共常数(如果有的话) 在ASP里将不再有效。这意味着我们需要自己声明它们域等价物)并指定相应的值 例如,当在早期版本的ASP中使用 ActiveX数据库对象(ADO)组件时(将在第8章进行详细 的研究),不得不用记录集的open方法加入预定义常数声明。例如 Const adopenKeyset =&Ho001 Const adLockPesgimistic &H0003 Const adcmarable &H0002 rs Open Contact,DSN=Global ExampleData: UIDe examples Password=i", adopenKeyset, adLockPessimistic, adcmdTable 另一种方法是使用# include指令在页面插入一个名为 adovbs inc的文件。该文件由 IIS/ASP 提供,包含ADO所需的所有预定义常数。更新代码时,必须确认使用的是最新版本,并检查 它对于所有的页面请求都可用。 对于IS50,有一个更好的方法,通过在HTML注释元素内使用 METADATA指令,可以 给组件或对象的类型库增加引用(IS40不支持这一功能)。 <! - METADATA TYPE=TypeLib UUIDa'typeItbraryuuda VERSION=mayor verdon number nor_ versiona LcID=·oca1e⊥d ath and name_ of file是某一类型库文件(:b)或 ActiveX dll的绝对物理路径,必须提 供这一参数或者是 pe library_uuid参数 ype library_uuid是该类型库的唯一标识符,必须提供这一参数或者是path_and name of file参数 major version number. minor version number(可选)定义了所需组件的版本。如果没有 该版本则使用最近的版本 · locale_d(可选)是区域标志符。如果在该区域没有发现类型库,计算机将使用缺省的(安 装时定义的)区域 因此,使用这一技术,通过使用下面的代码,能使内置的ADO预定义常数在ASP页面可 <I-- METADATA TYPE=TypeLib. FILE=c: \Program Files\Common Files\ System\ado\msadol5dll 文件名 sado l5d还可用于更高版本(250以后)的ADO组件
如果需要会话层组件,使用可用的双线程的组件。并且如果需要应用程序层作用域,可 一直使用双线程的组件。 然而,微软建议避免使用会话层作用域的组件,甚至不使用应用程序层作用域的组件, 除非这些组件是绝对需要的。使组件的活动时间超过作用域为页面级的组件所要求的时间, 对于由C O M +提供代理特性的对象是没有益处的。 5.2.5 引用对象类型库 在早先的A S P版本中,在脚本中使用对象或组件时,组件内定义的公共常数 (如果有的话) 在A S P里将不再有效。这意味着我们需要自己声明它们(或等价物)并指定相应的值。 例如,当在早期版本的 A S P中使用A c t i v e X数据库对象( A D O )组件时(将在第8章进行详细 的研究),不得不用记录集的O p e n方法加入预定义常数声明。例如: 另一种方法是使用# i n c l u d e指令在页面插入一个名为 a d o v b s . i n c的文件。该文件由I I S / A S P 提供,包含A D O所需的所有预定义常数。更新代码时,必须确认使用的是最新版本,并检查 它对于所有的页面请求都可用。 对于IIS 5.0,有一个更好的方法,通过在 H T M L注释元素内使用 M E TA D ATA指令,可以 给组件或对象的类型库增加引用 (IIS 4.0不支持这一功能)。 其中: • p a t h _ a n d _ n a m e _ o f _ f i l e 是某一类型库文件(.tlb )或ActiveX DLL的绝对物理路径,必须提 供这一参数或者是t y p e _ l i b r a ry_uuid 参数。 • t y p e _ l i b r a ry _ u u i d是该类型库的唯一标识符,必须提供这一参数或者是 p a t h _ a n d _ n a m e _ o f _ f i l e参数。 • m a j o r _ v e r s i o n _ n u m b e r. m i n o r _ v e r s i o n _ n u m b e r (可选)定义了所需组件的版本。如果没有 该版本则使用最近的版本。 • locale_id (可选)是区域标志符。如果在该区域没有发现类型库,计算机将使用缺省的 (安 装时定义的)区域。 因此,使用这一技术,通过使用下面的代码,能使内置的 A D O预定义常数在 A S P页面可 用: 文件名m s a d o 1 5 . d l l还可用于更高版本( 2 . 5 0以后)的A D O组件。 第5章 脚本运行期库对象计计139 下载
140Ap高程 Chinaopub.com 下载 如果ASP不能装载类型库,就返回一个错误并停止该页的执行。可能的错误提示如表5-1 表5-1错误提示代码及说明 ASP 0222 无效的类型库说明 ASP 0223 类型库不能加载 ASP 0225 类型库不能打包(即ASP不能从指定的类型库中创建类型库包装对象) 52.6在客户端上创建对象实例 在ASP中讨论在服务器上实例化对象和组件的技术时,值得强调的是在浏览器中运行客 户端页面而完成同样工作的方式。如果你使用ASP创建包含客户端脚本程序的页面,或者使 用元素创建客户端组件实例,将会发现这是非常有用的。在大多数情况下,脚本 运行期对象可在客户端上实例化和使用,效果与服务器上的ASP相同 1. VBScript CreateObject方法 在客户端使用 CreateObjecth时,在浏览器的环境内创建组件或对象实例,它们与浏览器运 行在相同的内存空间里(即进程内),除非实现的对象是带有exe扩展文件名的可执行文件 通常指定对象的 ClassID,而不是使用 ProgID字符串,这样就不可能与其他安装在客户端 的对象发生冲突 im obi This Set objThis Createobject("clsid: 892D6DA7-E0F9-11D2-B2E9-00105A42AF30 /SCRIPT 当然也可以使用 ProgID,并且使用通用的对象或组件(特别是标准安装提供的对象或组件) 那么得到错误的组件的风险是很小的 Dim ob]This Set objThis- Createobject("Scripting Dictionary ' var ta new Activexobject('this. object'); 3.元素技术 也可使用元素创建客户端对象或组件的实例。应省略 RUNAT属性或者将其设
如果A S P不能装载类型库,就返回一个错误并停止该页的执行。可能的错误提示如表 5 - 1 所示。 表5-1 错误提示代码及说明 错 误 说 明 ASP 0222 无效的类型库说明 ASP 0223 未找到类型库 ASP 0224 类型库不能加载 ASP 0225 类型库不能打包(即A S P不能从指定的类型库中创建类型库包装对象 ) 5.2.6 在客户端上创建对象实例 在A S P中讨论在服务器上实例化对象和组件的技术时,值得强调的是在浏览器中运行客 户端页面而完成同样工作的方式。如果你使用 A S P创建包含客户端脚本程序的页面,或者使 用元素创建客户端组件实例,将会发现这是非常有用的。在大多数情况下,脚本 运行期对象可在客户端上实例化和使用,效果与服务器上的 A S P相同。 1. VBScript CreateObject 方法 在客户端使用C r e a t e O b j e c t时,在浏览器的环境内创建组件或对象实例,它们与浏览器运 行在相同的内存空间里(即进程内),除非实现的对象是带有. e x e扩展文件名的可执行文件。 通常指定对象的C I a s s I D,而不是使用P r o g I D字符串,这样就不可能与其他安装在客户端 的对象发生冲突。 当然也可以使用P r o g I D,并且使用通用的对象或组件 (特别是标准安装提供的对象或组件 ), 那么得到错误的组件的风险是很小的: 2. JScript ActiveXObject方法 为了在客户端上实例化J S c r i p t的对象和组件,必须使用A c t i v e X O b j e c t方法和n e w操作符: 或: 3. 元素技术 也可使用元素创建客户端对象或组件的实例。应省略 R U N AT属性或者将其设 140计计ASP 3 高级编程 下载
hinaopub.com 141 下载 第5章脚本运行期库对象 定为“ CLIENT”。然而,这个属性在客户端上是被忽略的,因此设置这个属性的唯一目的就 是,在ASP页面使用元素实例化服务器端的组件实例时防止混淆 OBJECT ID='ob]This RUNAT="CLIENT CLASSID="clsid: 892D6DA7-EOF9-11D2-B2E9-00105A42AF30 OdebAse-hTtp://yourserver.com/components/'mycomponent.cab'> RAM NAME=" param1· VALUE="va工ue1"> RAM NAME="param2 VALUE=*value2> 注意,这里出现的 CODEBASE属性,表示允许下载并安装来自URL的组件(如果 该组件没有安装)。正E3.0以上的版本有此功能 对于使用COBJECT>元素的方法、可使用的属性、在客户端使用时的值,可查看网站http // msdn. microsoft. com/workshop/author/dhtml/reference/objects/OBJECT. asp, ai# Window 2000 Platform SDK文档中的tags”,或者看看《 IES Dynamic HTML Programme Reference》一书,ISBN1-861001-74-6,wrox出版社。 5.3 Scripting Dictionary.对象 许多 Microsoft的编程语言,如 Visual basic、 SCript和 JScript,都提供集合( collection) 可以把集合想象为数组,可以使用其中内建的函数完成存储和操纵数据等基本任务。无须担 心数据是在哪些行列,而是使用唯一的键进行访问。 VBScript和 JScript都提供类似的对象,通称 Scripting. Dictionary对象或 Dictionary对象。它 类似于二维数组,把键和相关条目的数据存放在一起。然而真正的面向对象的方式,不应直 接访问数据条目,必须使用 Dictionary对象支持的方法和属性来实现。 本章提供了一些示例页面,允许试验脚本运行期对象的方法和属性。这些实例 在下载的文件的 Chaper05子目录里 531创建和使用 Dictionary对象 创建一个 Dictionary对象的示例如下: In vBScript: Dim objMyData Set objMy Data Server Createobject(*Scripting Dictionary) / In JScript: ject('Scriptin th an oBjecT element -- Dictionary对象还可用于客户端的IE中 l. Dictionary对象的成员概要 表5-2和表5-3列出了 Dictionary对象的属性和方法及相应的说明。 当增加一个键/条目对时,如果该键已存在:或者删除一个键/条目对时,该关键字 /条目对不存在;或改变已包含数据的 Dictionary对象的 CompareMode,都将产生错误
定为“C L I E N T”。然而,这个属性在客户端上是被忽略的,因此设置这个属性的唯一目的就 是,在A S P页面使用元素实例化服务器端的组件实例时防止混淆。 注意,这里出现的C O D E B A S E属性,表示允许下载并安装来自 U R L的组件(如果 该组件没有安装)。IE 3.0以上的版本有此功能。 对于使用元素的方法、可使用的属性、在客户端使用时的值,可查看网站 h t t p: / / m s d n . m i c r o s o f t . c o m / w o r k s h o p / a u t h o r / d h t m l / r e f e r e n c e / o b j e c t s / O B J E C T. a s p,或者Wi n d o w s 2000 Platform SDK文档中的 t a g s”,或者看看《IE5 Dynamic HTML Programmer' R e f e r e n c e》一书, ISBN 1-861001-74-6,Wrox 出版社。 5.3 Scripting.Dictionary对象 许多M i c r o s o f t的编程语言,如Visual Basic、V B S c r i p t和J S c r i p t,都提供集合( c o l l e c t i o n )。 可以把集合想象为数组,可以使用其中内建的函数完成存储和操纵数据等基本任务。无须担 心数据是在哪些行列,而是使用唯一的键进行访问。 V B S c r i p t和J S c r i p t都提供类似的对象,通称 S c r i p t i n g . D i c t i o n a r y对象或D i c t i o n a r y对象。它 类似于二维数组,把键和相关条目的数据存放在一起。然而真正的面向对象的方式,不应直 接访问数据条目,必须使用 D i c t i o n a r y对象支持的方法和属性来实现。 本章提供了一些示例页面,允许试验脚本运行期对象的方法和属性。这些实例 在下载的文件的C h a p e r 0 5子目录里。 5.3.1 创建和使用D i c t i o n a r y对象 创建一个D i c t i o n a r y对象的示例如下: D i c t i o n a r y对象还可用于客户端的I E中。 1. Dictionary对象的成员概要 表5 - 2和表5 - 3列出了D i c t i o n a r y对象的属性和方法及相应的说明。 当增加一个键/条目对时,如果该键已存在;或者删除一个键/条目对时,该关键字 /条目对不存在;或改变已包含数据的D i c t i o n a r y对象的C o m p a r e M o d e,都将产生错误。 第5章 脚本运行期库对象计计141 下载
142Ap高程 Chinaopub.com 下载 表5-2 Dictionary对象的属性和说明 CompareMode (仅用于 VBScript)设定或返回键的字符串比较模式 Count 只读。返回 Dictionary里的键/条目对的数量 设定或返回指定的键的条目值 Key(key) 设定键值 表5-3 Dictionary对象的方法和说明 Add(key, item) 增加键/条目对到 Dictionary Exists(key) 如果指定的键存在,返回True,否则返回 False Items() 返回一个包含 Dictionary对象中所有条目的数组 Keys) 返回一个包含 Dictionary对象中所有键的数组 Remove(key) 删除一个指定的键/条目对 RemoveAll o) 删除全部键/条目对 2.对 Dictionary中增加和删除条目 旦得到一个新的(空的) Dictionary,可以对其添加条目,从中获取条目以及删除条目: ob Data Add 'MyKey,'MyItem Add value MyItem with key MyKe objMy Data Add *Yourkey, "YourItem Add value YourItem with key Yourkey bInIsThere objMyData Exists('MyKey''ReturnB True because the item asta strItem= objMy Data Item(Yourkey) Retrieve value of Yourkey strItem objMy Data Remove('My Key') Retrieve and remove Yourkey ob] Data. RemoveAll Rem。vea11 the ite 在 JScript中,等价的代码为 / In JScript: objMy Data Add('MyKey', 'MyItem') // Add value MyItem with key MyKey objMy Data Add('YourKey','YourItem / Add value YourItem with key Your key ar blnIsThere objMy Data Exists(' MyKey '); / true because the item exista var strItem m objMy Data Item('YourKey); / Retrieve value of YourKey var strItem objMy Data Remove('MyKey);// Retrieve and remove Yourkey objMyData. RemoveAll() / Remove all the items 3.修改键或条目的值 可以通过修改键的值,或通过修改与特定的键关联的条目的数据,来改变存储在 Dictionary内的数据。下面的代码改变键为 My Key的条目中的数据 objMy Data Item('MyKey)=NewValue In VBScript objMy Data Item(' ')-'NewValue': / In JScript 如果指定的键在 Dictionary未找到,将在 Dictionary中创建一个以 My Key为键,以 New value为其条目值的新的键/条目对。有意思的是,如果使用一个不存在的键来检索条目 不仅得到一个空的字符串(这是可以想到的),而且还在 Dictionary里添加一个新的键/条目对, 键即是指定的键,但条目的数据为空 可以使用Key属性仅改变键的值而不改变与之对应的条目的数据。将一个已存在的键 MyKey改变为 MyNewKey,可以用
表5-2 Dictionary对象的属性和说明 属 性 说 明 C o m p a r e M o d e (仅用于V B S c r i p t )设定或返回键的字符串比较模式 C o u n t 只读。返回D i c t i o n a r y里的键/条目对的数量 I t e m (k e y) 设定或返回指定的键的条目值 K e y (k e y) 设定键值 表5-3 Dictionary对象的方法和说明 方 法 说 明 A d d (k e y, item) 增加键/条目对到D i c t i o n a r y E x i s t s (k e y) 如果指定的键存在,返回 Tr u e,否则返回F a l s e Items( ) 返回一个包含D i c t i o n a r y对象中所有条目的数组 Keys( ) 返回一个包含D i c t i o n a r y对象中所有键的数组 R e m o v e (k e y) 删除一个指定的键/条目对 RemoveAll ( ) 删除全部键/条目对 2. 对D i c t i o n a r y中增加和删除条目 一旦得到一个新的(空的) Dictionary,可以对其添加条目,从中获取条目以及删除条目: 在J S c r i p t中,等价的代码为: 3. 修改键或条目的值 可以通过修改键的值,或通过修改与特定的键关联的条目的数据,来改变存储在 D i c t i o n a r y内的数据。下面的代码改变键为 M y K e y的条目中的数据。 如果指定的键在 D i c t i o n a r y未找到,将在 D i c t i o n a r y中创建一个以 M y K e y为键,以 N e w Va l u e为其条目值的新的键 /条目对。有意思的是,如果使用一个不存在的键来检索条目, 不仅得到一个空的字符串 (这是可以想到的 ),而且还在D i c t i o n a r y里添加一个新的键 /条目对, 键即是指定的键,但条目的数据为空。 可以使用 K e y属性仅改变键的值而不改变与之对应的条目的数据。将一个已存在的键 M y K e y改变为M y N e w K e y,可以用: 142计计ASP 3 高级编程 下载
Chinapub.com 第5章脚本运行期库对象 143 下载 objMyData. Key('Mykey)w"MyNewKey In VBScript 如果指定的键未找到,则产生运行期错误。 4.设置比较模式 Dictionary的 CompareMode属性仅适用于 VBScript,不能在 JScript中使用。当比较字符串 键时,允许指定比较的方式。两个允许的值为 Binary Compare(0)和 TextCom pare(1) Binary Compare(O)为二进制数对照(即区分大小写); TextCompare(1)为文本对照(即不区分大小 5.遍历 Dictionary 研究 Dictionary时,有两个方法和一个属性需要特别注意,它们允许我们遍历存储在 Dictionary里的所有键/条目对。 Items方法用一个一维数组的形式返回 Dictionary里所有的条目 数据,而keys方法用一个一维数组返回所有已存在的键值。可以使用 Count属性得到键或条目 的数量 例如,可以使用下列代码得到名称为 bjMyData的 Dictionary中所有的键和条目值。注意, 虽然 Count属性保存了在 Dictionary里的键/条目数量,但Ⅴ SCript和 JScript的数组总是从下标0 开始的。因此,数组下标应从0到 Count-1。 In vBScript: arrKeys objMy Data keys Get all the keys into an array arrItems w objMy Data. Items 'Get all the items into an array For intLoop =0 To objMyData, Count -1 'Iterate through the array strThisKey arrkeys (intLoop) 咄h"th·keyv1ue sErThisIt *ThiB 18, the item (data)value / In JScript: VB-Btyle using the Keys()and Items()methods ray (obyMy Data Keys()).toArray ()1 Array(objMy Data. Items ()) toArray(); tloop =0; intLoop ob]MyData Count; intLoop++)( erate through the a chi skey arrKeys[intLoopl; №⊥ the key va】ue lisTen /4 the item (data) value 在 VBScript里也可以使用 For each Next语句完成同样的功能 Iterate the dictionary as a collection in VBScript frItes Net esponse. Write objItem,=·岳 ariteus( objItem)k·<BR 532 Dictionary对象示例 本书提供了一系列示例文件可用来试验脚本运行时间库的各种属性。 本章代码的缺省页面提供了一系列可使用的 SCript示例链接。有些示例对 JScript同样有 效。这些示例存放在 Chapter目录下相应的子目录里,显示的界面如图5-2所示
如果指定的键未找到,则产生运行期错误。 4. 设置比较模式 D i c t i o n a r y的C o m p a r e M o d e属性仅适用于V B S c r i p t,不能在J S c r i p t中使用。当比较字符串 键时,允许指定比较的方式。两个允许的值为 B i n a r y C o m p a r e ( 0 )和Te x t C o m p a r e ( 1 )。 B i n a r y C o m p a r e ( 0 )为二进制数对照(即区分大小写);Te x t C o m p a r e ( 1 )为文本对照(即不区分大小 写)。 5. 遍历D i c t i o n a r y 研究D i c t i o n a r y时,有两个方法和一个属性需要特别注意,它们允许我们遍历存储在 D i c t i o n a r y里的所有键/条目对。I t e m s方法用一个一维数组的形式返回 D i c t i o n a r y里所有的条目 数据,而k e y s方法用一个一维数组返回所有已存在的键值。可以使用 C o u n t属性得到键或条目 的数量。 例如,可以使用下列代码得到名称为 b j M y D a t a的D i c t i o n a r y中所有的键和条目值。注意, 虽然C o u n t属性保存了在D i c t i o n a r y里的键/条目数量,但V B S c r i p t和J S c r i p t的数组总是从下标0 开始的。因此,数组下标应从 0到Count - 1。 在V B S c r i p t里也可以使用For Each...Next 语句完成同样的功能: 5.3.2 Dictionary对象示例 本书提供了一系列示例文件可用来试验脚本运行时间库的各种属性。 本章代码的缺省页面提供了一系列可使用的 V B S c r i p t示例链接。有些示例对J S c r i p t同样有 效。这些示例存放在C h a p t e r 0 5目录下相应的子目录里,显示的界面如图 5 - 2所示。 第5章 脚本运行期库对象计计143 下载