One of the most common problems you may face when creating ActiveX DLLs for use with WebClasses is that there's no ObjectContext object available to your WebClass. By default, although WebClasses are instantiated from an ASP page that does have access to the MTS ObjectContext object, WebClasses do not have access to the ObjectContext object. You can't obtain a reference to the ObjectContext with a call to getObjectContext. The WebClassManager object passes references to the other ASP variables when it launches a WebClass, but it does not pass a reference to either the ScriptingContext object or the (obsolete) ObjectContext object.
What is the ScriptingContext object and why would you want to obtain a reference to it? Let me give you a little history. The first version of ASP did not include a public ScriptingContext object. Instead, the ASP engine called OnStartPage and OnEndPage methods on external DLLs. ASP still supports these methods in all versions.
Just after instantiating each ActiveX object created on a page, ASP calls the On-StartPage method for that object and passes the ScriptingContext object as the only argument. Any ActiveX object that implements the method can gain references to the intrinsic ASP objects. For example:
Public Sub OnStartPage(sc as ScriptingContext)
Set mApplication = sc.Application
Set mSession = sc.Session
Set mResponse = sc.Response
Set mRequest = sc.Request
Set mServer = sc.Server
End Sub
Just before destroying the object when the page ends, the ASP engine calls the OnEndPage method. When the OnEndPage event fires, the object can release the references:
Public Sub OnEndPage()
Set mApplication = Nothing
Set mSession = Nothing
Set mResponse = Nothing
Set mRequest = Nothing
Set mServer = Nothing
End Sub
Objects that implement these two methods have an automatic way of gaining references to the ASP objects. Thus, you could write code in an ActiveX DLL that used the values stored in Session objects and could write output back to the browser, via the Response object.
In the second version of ASP, released with the NT 4 Option Pack and IIS 4, Microsoft directly exposed the ScriptingContext object. Web applications in IIS 4 and later all run under MTS; therefore, Microsoft now recommends that apartment-threaded ActiveX objects no longer use the OnStartPage and OnEndPage methods. Instead, you should add two project references: one to the Microsoft Transaction Server Type Library and one to the Microsoft Active Server Pages Object Library. You can then use the getObjectContext method to obtain the ASP ObjectContext object reference, then use that to gain access to the other intrinsic ASP objects:
Public Function TestResponse()
Dim objContext As ObjectContext
Dim mResponse as Response
Set objContext = GetObjectContext()
Set mResponse = objContext("Response")
mResponse.Write "Hello World"
set mResponse = Nothing
End Function
That's enough history. Here are the problems: The code shown in the Test-Response function works fine as long as you create the object from an ASP page, but the same code doesn't work inside a WebClass. This is surprising—you would expect that the WebClass would run under MTS because the ASP page that launches a WebClass runs under MTS.
Microsoft's explanation for this behavior is that WebClasses don't run under MTS because they needed to be compatible with IIS 3. As you'll soon see, that was an unfortunate choice because it causes additional problems.
When you create an ActiveX DLL object from a WebClass that's not running under MTS, you cannot get a reference to the ObjectContext object by creating the object with the New keyword. Luckily, you can solve this problem in two ways:
•
Use the Server object's CreateObject method from inside the WebClass to create the ActiveX object. ActiveX objects created in this manner do have access to the ObjectContext, even though the WebClass does not.
•
Because the compiled WebClass is also an apartment-threaded ActiveX DLL, you can run it in a package under MTS with no problems. After your WebClass is running in a package, you can get an ObjectContext, add other ActiveX DLLs to the package, and everything works fine.
Note
In Chapter 9, "Dealing with Multiple Browsers," I promised to tell you how to use the MSWC.BrowserType component from WebClasses. Here's the answer: Use the Server.CreateObject method to instantiate the component, and it will work exactly as it does from an ASP page.