4.3.2 创建其他对象的实例 在前一章中,讨论了ASP的虚拟应用程序概念,了解了虚拟应用程序通过application Protection设置为ASP网页中的组件和其他对象提供进程隔离。这延续了第1章的讨论,即ASP的ObjectContext对象如何为ASP网页提供运行环境,以及如何使用在相同的环境中运行的其他组件和对象。 ASP Server对象提供创建这些组件和应用程序实例的功能,因此可用来扩充ASP脚本的能力。通过实现CreateObject方法的一个特定版本来实现这个功能。 1. 在VBScript和JScript中创建对象实例 在VB或VBA中,可使用多种方法创建对象的实例。可以使用New关键字来创建指定类型的一个新对象: Dim objNewObject As New MyComponent 然而,不能在ASP中用VBScript或JScript这么做,因为这些脚本引擎不能实现数据类型定义。不能声明一个变量为任意指定的数据类型,其变量都是Variants类型,或一个等价的类型(根据使用的脚本语言而定)。 在VB和VBA中另一个方法是使用CreateObject或GetObject方法。CreateObject方法的参数是一个ClassID(通常情况)或一个ProgID字符串,它返回相应类型的一个新对象: Set objNewObject = CreateObject(“ADODB.Connection”) 当拥有一个指定的文档类型,并且想创建一个可以处理这种文档的对象实例时,通常使用GetObject方法: Set objExcel = GetObject(“C:/myfiles/sales.xlw”) 也可以指定所需要的对象类型和文件名,在几种对象都能处理该文档类型的情况下,这种做法是非常有用的: Set objExcel = GetObject(“C:/myfiles/sales.xlw”,”Excel.Application”) VBScript支持CreateObject和GetObject方法。JScript也有getObject方法,与VBScript中的GetObject工作方式相同。JScript中的ActiveXObject实现了与VBScript的CreateObject方法相同的功能。但这个函数常与JScript的new运算符协同使用: ObjNewObject = new ActiveXObject(“This.object”); 除了VB的NEW关键字在VBScript和JScript中不予支持以外,能够使用所有这些技术在一个ASP网页中创建对象的实例。然而,能够并不意味着应该,而且大多数情况下不应该在一个ASP网页中使用脚本引擎的对象创建函数。 2. 在ASP网页中创建对象实例 为了理解一般的脚本引擎对象创建方法为什么在ASP网页中使用效果不理想,需进一步对ASP中的环境和ObjectContext对象进行讨论。 使用脚本引擎的一般方法在一个ASP网页中创建一个对象实例时,该对象在当前执行的页面的环境中并未实例化。得不到ObjectContext对象的引用,所以不能使用该对象来访问页面的环境,即不能访问该页面环境中的值。 这意味着该对象不能使用内置的ASP对象,即不能够访问在Request、Response、Application和session对象的集合中的值,也不能使用内置的ASP对象提供的方法和属性。该对象也不能够与此环境中任何现有的事务进行交互。如果发生错误,不能使用ObjectContext方法放弃一个事务。 当然,你可能不想与该网页的环境进行交互。但是有其他的理由说明使用一般的对象创建方法通常是不明智的。IIS自动地在COM+运行期包装程序hllhost.dll中实例化对象,使得该对象可以在当前的虚拟应用程序中完全地共享和重新使用(缺省的Web网站本身是一个虚拟的应用)。 你在上一章所看到的对一个虚拟应用程序的设置,既允许在Web服务器的内存空间中创建对象,也可以在共享的或独立的进程外DLLHost.dll实例中创建对象。如果使用一般的脚本引擎对象创建方法,将绕过所有的组件隔离和可扩展特性。而在使用ASP Server对象的CreateObject方法时会自动地提供这些特性。 3. Server对象的CreateObject方法 为了试验CreateObject方法,打开示例的Chapter04主菜单页,单击“Using the ASP Server Object”链接,如图4-10所示:
图4-11 Server对象的属性和方法 在该页面的“Create an Instance of a Component”区域,有一个文本框,可以在其中键入想要在该网页的环境中创建的对象的ProgID字符串,甚至可以键入一个ClassID数值。这里文本框的缺省值已经设置为一个来自ActiveX数据对象库的公用对象的ProgID:ADODB.Connection。 单击“Server.CreateObject”选项旁的按钮,把该页面提交给其自身,因为所有的控件都在一个带有ACTION属性的<FORM>上,而这个ACTION属性被设置为这个网页的路径和文件名: … FORM ACTION="<% = Request.ServerVariables("SCRIPT_NAME") %>" METHOD="POST">
<P><DIV CLASS="subhead">Create an Instance of a Component</DIV> <INPUT TYPE="SUBMIT" NAME="cmdCreateObject" VALUE=" "> Server.CreateObject (" <INPUT TYPE="TEXT" NAME="txtProgID" SIZE="25" VALUE="ADODB.Connection"> ")<P> … </FORM> … 当该页面重新载入时,该页中的一段ASP代码(位于<FORM>段的前面)将查看提交该窗体时,单击了哪个按钮。如果是名称为“cmdCreateObject”的按钮时,该代码将读取文本框中的ProgID字符串。为防止用户输入的ProgID无效而导致执行中止,关闭缺省的脚本错误处理,再尝试使用Server.CreateObject方法创建一个对象的实例。最后,再重新打开缺省的错误处理,通过使用IsObject函数检查是否创建了一个对象实例,并显示一个相应的信息: QUOT = Chr(34) 'double-quote character … 'look for a command sent from the FORM section buttons If Len(Request.Form("cmdCreateObject")) Then strProgID = Request.Form("txtProgID") On Error Resume Next Set objObject = Server.CreateObject(strProgID) On Error Goto 0 If IsObject(objObject) Then Response.Write "<B>Results:</B><BR>Sucessfully created object with ProgID of <B>" _ & QUOT & strProgID & QUOT & "</B><HR>" Else Response.Write "<B>Results:</B><BR>Failed to create object with ProgID of <B>" _ & QUOT & strProgID & QUOT & "</B><HR>" End If End If … 图4-12所示的是创建ADODB.Connection对象的结果。可以看到该对象已被正常实例化,已可以在代码中使用。