In all likelihood, when you begin the move to ASP.NET, you will not be rewriting your existing application but rather slowly migrating it from ASP to ASP.NET. This section focuses on is how to run ASP and ASP.NET together and how to interact with existing investments in COM servers from ASP.NET. I recommend that you also read the “Migrating to ASP.NET” section of this chapter, however, because the points are still applicable for integration.
The configuration systems used by ASP and ASP.NET are completely separate. Whereas ASP relies on settings found in Internet Information Service’s metabase, ASP.NET uses an XML-based configuration architecture. The majority of ASP-related settings can be easily configured by opening up Internet Information Services, right-clicking on a Web site, and selecting Properties. With the Properties dialog box open, select the Home Directory tab and click the Configuration button. This opens the Application Configuration dialog box, which is shown in Figure 11-2, earlier in the chapter.
You can find ASP settings on the Options tab or the Debugging tab of the Application Configuration dialog box. These configuration options include:
Enable/Disable Session State Indicates whether or not ASP sessions are enabled.
Session State Timeout Timeout value for Session. If the session is not refreshed or used before the timeout expires, the session data is removed from memory.
Request Buffering By default, request buffering, the ability to buffer the entire request before writing the response back to the calling browser, is enabled.
Default Language The default script language is VBScript.
Script Execution Timeout The amount of time a script is allowed to execute before being automatically shut down due to timing out.
Client/Server Debugging Options Controls debugging ASP applications.
Script Error Messages Error message displayed when an error occurs within an ASP.
These settings affect only ASP. If ASP.NET was also installed, and ASP.NET pages were present in this Web site or application, these settings would not affect the ASP.NET application whatsoever. ASP.NET uses its own XML-based configuration files.
ASP.NET’s XML configuration file is both easier to use and simpler to manage than the one used by ASP. For example, when running in a server farm, rather than having to individually manage each machine by manually configuring IIS through the IIS GUI, the ASP.NET administrator can simply manage the ASP.NET application by making changes to the XML configuration file and copying that file to the server.
ASP.NET supports two types of configuration files, machine.config and web.config. The machine.config file is the root, or parent, configuration file found in a version-specific directory for the version of ASP.NET you have installed. There can only be one machine.config for each version of ASP.NET you have installed. (ASP.NET is designed to allow different versions to run side by side. ASP.NET 1 and ASP.NET 1.1 can run on the same server without affecting each other another, and in the future ASP.NET 2 will be able to as well.)
Each application can have its own copy of web.config. The web.config file overrides or adds new configuration information to the configuration information originally defined by machine.config.
At the time of writing, two versions of ASP.NET are available: 1.0 and 1.1. These versions correspond to the following directories under either the Windows or WINNT directories: Microsoft.NET\Framework\v1.0.3705\ and Microsoft.NET\Framework\v1.1.4322\. Within each of these directories, you will find a config subdirectory, and within the config subdirectory, you will find the machine.config file.
One of the great benefits of ASP.NET’s XML-based configuration files is simplicity. For example, the following markup is the web.config file used to configure settings within ASP.NET that are comparable to the settings we discussed for ASP:
<configuration>
<system.web>
<httpRuntime executionTimeout="90" />
<compilation debug="false"
explicit="true"
defaultLanguage="vb" />
<pages buffer="true" />
<customErrors mode="RemoteOnly"/>
<sessionState mode="InProc"
cookieless="false"
timeout="20"/>
</system.web>
</configuration>
The preceding web.config file shows a much abbreviated version of what we can expect to find in machine.config. However, it does show how to configure common settings such as session, default language, and page buffering— settings that are similar to those we set for ASP. Another great benefit of the ASP.NET configuration system is that you can write your own configuration section handlers; that is, you can embed your own XML syntax for configuring your application within ASP.NET configuration system. This is done by implementing the IConfigurationSectionHandler class. (Chapter 7 reveals more about how the ASP.NET configuration system works and offers a thorough discussion of how to write a configuration section handler.)
In most cases, integration between your existing ASP application and ASP.NET takes place with existing ASP investments with COM. COM is still fully supported within .NET, however, we recommend that if you own the code for the COM objects, you consider rewriting them for .NET. Calling COM from .NET has a performance penalty, namely a marshalling cost incurred where data types must be coerced and converted.
Code written for the common language runtime is commonly referred to as managed code; that is, the running code is managed by the CLR. The term unmanaged code refers to any code written to run outside of the CLR, such as Visual Basic 6 or C++. (See Figure 11-5.) The CLR has a common type system, and all managed compilers can generate type equivalent code. So you can expect that Visual Basic .NET and C# code are type and functionally equivalent if similar code is written in each language. Unmanaged code relies upon the COM binary standard to dictate a common interface so that objects can interact with one another. For managed and unmanaged code to work together, there must be a coercion of types.
Figure 11-5: Separation between managed and unmanaged code
Some data types can be automatically converted, such as a Visual Basic 6 Integer data type, and some types cannot be automatically converted, such as the C++ BSTR. Tables 11-2 and 11-3 list the conversions. For types that can’t be automatically coerced to a corresponding type on the unmanaged side, you can coerce the type yourself.
Visual Basic Type | C++ Type | .NET Type |
---|---|---|
Integer | Short | Short |
n/a | unsigned int | UInt32 |
n/a | __int64 | Long |
n/a | unsigned __int64 | UInt64 |
Long | Int | Integer |
n/a | unsigned short | UInt16 |
n/a | signed char | SByte |
Byte | unsigned char | Byte |
Single | Float | Single |
Double | Double | Double |
Char | __wchar_t | Char |
n/a | Void | Void |
Visual Basic Type | C++ Type | .NET Type |
---|---|---|
Variant | VARIANT | Object |
Object | IUnknown | UnmanagedType.IUnknown |
Date | DATE | Date |
Currency | CURRENCY | Decimal |
String | BSTR | String |
Boolean | BOOL | Boolean |
In the COM world, a type library is used to describe the types used by that COM object. In .NET, all this type information is stored in the manifest of the assembly—simply put, this same type information is stored in the .dll that is generated by a .NET compiler. There is no separate type library. When working with COM objects, you can import a type library. By importing a type library, .NET can create a run-time callable wrapper class for the COM object.
A run-time callable wrapper simply provides a wrapper class around the existing COM server and hides the unknown COM types from the .NET developer. A run-time callable wrapper can be generated automatically when using a COM server in a Visual Studio .NET project or by using the command-line tool tlbimp.exe. (Another tool, tlbexp.exe, allows you to create a type library for a .NET class. This then allows the .NET class to be callable and used by COM.)
All code complied for .NET, such as Visual Basic .NET, creates free- threaded objects. One of the major changes for ASP.NET is that it executes in a multithreaded apartment vs. the single-threaded apartment (STA) model used in ASP. Essentially, this means that in ASP.NET, multiple threads can be working together and operating on the same data within the process. Without going into too much detail, from a performance perspective, this is a good thing. ASP.NET uses a different thread for each request and additionally creates new instances of all required pages and classes on each request, so we still get the benefits of a multithreaded environment without having to worry about multithreading issues. The only problem is the interoperation of COM with Visual Basic 6 components or other COM objects that run in a single-threaded apartment.
Visual Basic 6 is capable only of creating code that must be run in an STA. What this means for the ASP.NET developer is that ASP.NET applications that interoperate with a single-threaded apartment COM server, such as Visual Basic 6 components, can behave unpredictably. (The main issue has to do with reference counting of the object and the ability of .NET to properly clean up and dispose of an STA component.) To address this problem, ASP.NET provides an ASPCompat page directive that forces the page to run on a special STA thread:
<%@ Page ASPCompat="true” %>
If you attempt to use a Visual Basic 6 component without marking the page as ASPCompat=“true”, you might or might not get an exception. You will likely see inconsistent or odd behaviors once you put your application into production.
Another side effect of marking a page as ASPCompat is that the ASP intrinsic ObjectContext will be available. ObjectContext in ASP was used to flow context information about the request from ASP to business objects running within ASP. If your COM code depends on ObjectContext, you’ll need to use ASPCompat=“true”. Note that using ASPCompat will degrade the performance of the ASP.NET page.
Many developers rely upon the Session and Application objects within ASP to share and store information about users or the application. Although these objects do still exist in ASP.NET, there is no integration point when running ASP and ASP.NET together in the same application. Data stored in Session within ASP is not available in the ASP.NET application.
For the Application intrinsic object, this lack of integration is usually not too much of a problem. However, if the application relies on Session, getting ASP and ASP.NET to work together is more difficult. The usual recommendation is that you replace all ASP and ASP.NET Session usage with a common object that is shared by both and stores its data in a database. You’ll be writing your own session manager, but you can then take control over where the data is stored and provide a common interop layer for ASP and ASP.NET.