This article may contain URLs that were valid when originally published, but now link to sites or pages that no longer exist. To maintain the flow of the article, we've left these URLs in the text, but disabled the links.
|
Creating Internet Applications with Visual Basic
|
In this and future installments of our new column, Advanced Basics, we'll show you how you can use Visual Basic to develop real-life Web solutions in conjunction with ASP, MTS, and other Web-centric Microsoft technologies. |
Since this is the feature-length debut of what will be a regular column, I'd like to give you an overview of the topics I plan to cover in the next year. I will focus on writing Internet Information Server (IIS)-based applications using Visual Basic® as the primary development tool. I'll show you how to write server-side Visual Basic code that uses Windows NT middle-tier services such as Active Server Pages (ASP), Microsoft Transaction Server (MTS), and Microsoft Message Queue (MSMQ). If you're creating Internet-style applications using Windows NT Server, then this column should be right up your alley. I'll assume you are at an intermediate to advanced level with Visual Basic and are comfortable with the fundamentals of COM-style development. I'll also assume you have had some exposure to HTML and writing Active Server Pages using built-in ASP objects such as the Request, Response, Session, Application, and Server. I will focus on cross-platform development. The topics I write about should be equally useful to developers who are trying to reach users with a variety of browsers and platforms. This means you can create applications using IIS, MTS, MSMQ, and SQL Server that are accessible to users running Netscape Navigator on platforms such as Unix or the Macintosh. This month I will cover the core aspects of IIS programming with Visual Basic. I will examine the IIS runtime environment and discuss how the Windows NT 4.0 Option Pack release melded the MTS runtime environment with IIS. I'll also discuss creating and using Visual Basic objects within a Web-based application. Along the way, I will try my best to convince you to maintain the majority of your application logic in DLLs using Visual Basic as opposed to the combination of Active Server Pages with a scripting language.
Creating an Object from an Active Server Page
|
|
This snippet shows you how easy it is to create and use a Visual Basic object from an ASP page. Note that the ASP filter recognizes the inline tags <% and %> as the beginning and the end of a server-side script. Figure 2 shows what the resulting page looks like in a browser. |
![]() |
Figure 2: CTableBuilder Output |
Once again, I must emphasize that this is a cross-platform solution; I just happened to use Microsoft Internet Explorer here. You can run as much COM code as you'd like on the Web server as long
as you pass a pure HTML stream back to the client. It's up
to you to know which HTML tags create browser-specific dependencies.
Replacing ASP Code with Visual Basic
There are a few quirks involved when writing ASP code with VBScript. First, all your variables must be variants. This takes some getting used to for the average programmer. Second, VBScript can currently retrieve output parameters only when they are declared as variants. If you try to call a method on a Visual Basic object that has an output parameter defined as a String or a Double, the VBScript code will fail and generate a confusing error message. This implies that you should design your Visual Basic methods so that output parameters (such as ByRef) are variants when you intend to call them from ASP scripts. There's no problem propagating Visual Basic errors from a DLL back to an ASP client. Error handling isn't as graceful in VBScript as it is in Visual Basic. You must conduct error handling by using an On Error Resume Next statement and checking the error number after each call. This is somewhat cumbersome, but it works. Here's an example of handling an error raised in a Visual Basic DLL with a VBScript client: |
|
IIS and MTS Marry
The Windows NT 4.0 Option Pack provides a new level of integration between IIS and MTS. Figure 3 shows the IIS Web server process (inetinfo.exe). As you can see, this process loads the MTS Executive (mtxex.dll). Installing the Windows NT 4.0 Option Pack automatically creates an MTS library package named IIS In-Process Applications. If you locate this package in the MTS Explorer, you'll see that it is preconfigured with a set of Web application manager (WAM) components. WAM components are registered with MTS, which means that WAM objects are MTS objects. WAM objects communicate with the MTS runtime through their object context just like any other MTS object. |
![]() |
Figure 3: IIS Web Server Process |
A WAM object is responsible for creating an ASP filter when the IIS Web server processes an ASP page request. This ASP filter parses server-side scripts from the page and runs them before returning control to the client. Figure 3 shows a simplified picture of a single WAM object creating an ASP filter. In most cases, a client request for an ASP page passes between several WAM objects before being processed. WAM objects are very sophisticated in their use of thread pooling and thread dispatching. While the low-level details of how WAM objects work shouldn't concern you too much, you should understand that a WAM object is ultimately responsible for creating an ASP filter when a client requests a Web page with an .asp extension. I will revisit this topic and take a closer look at the COM object behind an ASP filter a little later.
Deployment Options
|
![]() |
Figure 4: Isolated ASP Application |
Running an ASP application in isolation can provide greater isolation and fault tolerance in a production environment. You should note that this extra fault tolerance comes at a price. Every Web request must be redirected from a WAM object in the IIS Web process to a WAM in the isolated process, which has a negative impact on performance. Running your objects inside the IIS Web process will always be faster. When you're developing your components with Visual Basic, you'll probably want to run your ASP application as an isolated process. When you are writing and testing a Visual Basic DLL for an ASP application, you'll find that you need to unload the application's process before rebuilding the DLL. This is a real pain if you've loaded a DLL into the IIS Web server process because you have to shut down two separate IIS services before you can rebuild your DLL. However, the Properties dialog box for an isolated ASP application gives you the option of unloading the ASP application's process from memory. Once you unload the ASP application, you can rebuild any DLLs it has loaded. When you specify your ASP application to run in an isolated process, IIS configures your ASP application to run in a new instance of the MTS container application (mtx.exe). IIS also creates a new MTS server package dedicated to your ASP application. For example, if you mark a virtual directory named MindSite to run in isolation, a package named IIS-Default Web Site//Root/MindSite will be created automatically. You can install your Visual Basic components into this server package if you want your objects to run in this process. You can also create a secondary library package. Remember that objects created from an MTS library package will always be loaded into the process of their creator. Another deployment option is to run your Visual Basic objects inside their own MTS server package, as shown in Figure 5. To accomplish this, you should create a new server package with the MTS Explorer, and install your components inside it. What are some of the advantages of doing this? When you plan to execute MTS transactions from an ASP page, consider running your Visual Basic objects in a separate MTS server package for security reasons. Let's take a brief look at what you can do with a custom MTS server package. |
![]() |
Figure 5: MTS Server Package |
When you run your MTS transactions in the same process as your ASP code, you rely on IIS to authenticate each user. If the ASP application has been configured to allow anonymous access, any Internet user can run your transactions. If you run your transactions in a separate MTS server package, you can use the MTS role-based security model to give you more control over which users can run transactions. This makes it possible to grant access permission to authenticated users with Windows NT domain accounts, while denying access to anonymous logons on a component-by-
component basis. In addition, when you run your components in a custom MTS server package, you can decide which Windows NT user account your Visual Basic objects will run as. When you create an MTS server package with the MTS Explorer, you can assign the package's identity to any local or domain account. This means that all your business logic and data access code will run with the credentials of a single, dedicated business account of your choosing. This is a common approach in a large three-tier system. What's really neat about these three different deployment options I've just described is that none of them change the way you write either your ASP or Visual Basic code. You can change from one of these deployment options to another simply by changing the attributes of ASP virtual directories and MTS packages; there's no need to change your code. For example, you can test your code in the development environment by running your ASP application as an isolated process. When it's time to put your code into production, you can run the ASP application in the IIS Web server process to achieve better performance.
Your New Runtime Environment
|
![]() |
Figure 6: Interobject Communication |
When you program against the five built-in ASP objects from a script in an Active Server Page, you are actually calling methods through this implicit scripting object. However, you can also program directly against these built-in ASP objects from inside your Visual Basic DLLs. Figure 6 shows how the lines of communication
must be set up between the scripting object and a Visual Basic object. Once you create the connection from your Visual Basic object back to the scripting object, you can program against built-in ASP objects such as Request and Response from inside your Visual Basic DLL. An ASP scripting object exposes an interface named ScriptingContext that lets you get at the five built-in ASP objects. Before you can use any ASP objects in your Visual Basic project, you must reference the ASP type library. Figure 7 shows the ASP type library as seen through the Object Browser. Notice that the built-in ASP objects are exposed as COM objects. |
![]() |
Figure 7: ASP Type Library |
IIS 3.0 was the first release that let you program against the built-in ASP objects. The trick is to use the scripting object's ScriptingContext interface, which lets you navigate to the five other ASP objects. However, you'll need a little assistance to get to the ScriptingContext interface. When you call Server.CreateObject from an ASP page, IIS creates a new object and attempts to call into it through a special method named OnStartPage. If the call to OnStartPage succeeds, IIS passes a ScriptingContext reference to the new object. If the object doesn't implement OnStartPage, the call fails and IIS ignores the error. If you implement this method in a Visual Basic component, you can cache and use this ScriptingContext reference. The following code shows a Visual Basic class that does exactly this: |
|
The previous code shows how to retrieve the Request object from the ScriptingContext interface. Once you retrieve a reference to a built-in ASP object, you can program against it as if you're in an Active Server Page. However, as you know, Visual Basic provides many advantages over writing ASP code, such as IntelliSense and compile-time type checking. Remember, this is all possible because you're programming directly against the ASP type library. Your code will also run much faster than VBScript code because it is compiled and it uses direct vtable binding instead of IDispatch. Using OnStartPage to get at the built-in ASP object is a technique that became obsolete with the release of IIS 4.0. Now you can get at the five built-in ASP objects without using the ScriptingContext interface. The built-in ASP objects are now available through ObjectContext interface in MTS. As you've seen, a call to Server.CreateObject creates a new MTS object with a context wrapper and an object context. Server.CreateObject also populates the object context's Item collection with the five built-in ASP objects. The following Visual Basic code shows how to retrieve the Request object using the ObjectContext interface: |
|
This is a very powerful technique because it allows you to do so much more with Visual Basic. You can scrape values from the input controls in an HTML form, access the ServerVariables from the Request object, and create and access Session and Application variables. In short, you can do just about anything in your Visual Basic DLL that you can do in an ASP script. Here are some things to keep in mind. The scripting object created by IIS will only live for the duration of one page request. Once you retrieve a reference to one of the built-in ASP objects, you cannot hold it across multiple client requests. For that matter, the Visual Basic objects created from an Active Server Page should only live for the duration of the page itself. This means that your Visual Basic objects should also live and die within the scope of a single page request. The best way to write a Visual Basic class for IIS is to create a single method called Main. You should create an object in an ASP script and quickly pass control to the Visual Basic object by calling Main. You usually don't pass any parameters to Main because your Visual Basic code has access to the same information in the built-in ASP objects as the Active Server Page. Here's a minimal Active Server Page: |
|
This Active Server Page doesn't even contain any HTML code for the user interface; it simply serves as the entry point into your Visual Basic DLL. You can create all the required HTML right inside your Visual Basic DLL. Figure 8 shows a Visual Basic class named CMyWebComponent that generates all the HTML for an entire page and streams it back to the client through the ASP Response object. As you can see, it's possible to do just about everything from Visual Basic. Whether you want to take it to this extreme is a matter of programming style. Let's look at some of the important issues that you must weigh when deciding how much logic you should put into your Visual Basic DLLs and how much you should leave in Active Server Pages.
Striking a Balance Between Visual Basic and ASP
Web Classes and the IIS Application Designer
Next Column
|
From the December 1998 issue of Microsoft Interactive Developer.