Isolating ASP .Net Applications
|how-to | home|
ASP .Net 1.x has built-in support for Windows unmanaged (win32) side-by-side functionality. ASP .Net 2.0 dropped that support. There is no built-in mechanism to isolate access to unmanaged resources. It is still possible to to isolate ASP .Net 2.0 and higher applications, but some additional steps are required. In the past we suggested that an activation context could be activated and deactivated during an ASP .Net request processing using HTTP modules. In the end this approach does not work because ASP .Net may switch win32 threads during page processing. This results in no activation context or a wrong activation context on the thread processing this request and the thread with the desired activation context performing some other tasks. Read more about the failing approach.
There is no way to reliably intercept win32 thread switches in ASP .Net and, therefore, there is no way to turn win32 activation context on and off for the entire application. There are two possible solutions:
These solutions are not exclusive and can be used together to provide a default manifest for the entire application pool and change it as necessary during the web application processing.
Programmatic manipulation of the activation context requires using the Win32 SxS APIs. They can be called using .Net interop facilities. The calls are quite straightforward but it is important to keep track of side-by-side cookies (not related to HTTP cookies) and deactivate the contexts in the proper order. See How to Use the Activation Context API for more details and examples.
Setting the activation context for the entire process is similar to creating an application manifest for the executable that created the process. The difference is that if there is a manifest for the process, every instance of this process gets the same process default activation context and we are free to use any manifest for each process instance when we do this programmatically. Another difference is that the program manifest is activated before any DLLs are loaded which means that loading static imports is affected by the activation context. If the process default activation context is set programmatically it is set after all static DLLs have been loaded.
The process default activation context is always searched if the current activation context does not contain the definition of the required resource (DLL, CLSID, ProgID etc.) So it is possible to place common definitions in the process default activation context and only activate another activation context if a special or rarely used resource is necessary.
Once the process activation context is set, it cannot be removed or changed in any way and it is immediately effective for all threads in this process.
The process default activation context can be set at any time, as long as it has not yet been set. We could use any piece of code executing in the current application pool to perform this task. We suggest using an HTTP module's Init method. Such approach does not require any changes in the web application itself, uses a documented ASP .Net behavior, guarantees creation of the activation context quite early in the ASP .Net cycle and only executes when HTTP modules are being initialized - does not impact performance by executing the code on every web request.
An example HTTP module that creates the process default activation context for the application pool is included in Manifest Maker examples. Read more about the example.
The module only
implements the Init method and uses hard-coded manifest name
You can use this module as-is or you can build your own HTTP module that
implements a more elaborate logic of creating the application context. One such
improvement could be using the web.config file to store information on the
manifest and assembly root folder. It would then be possible to define a common
library of assemblies in some folder on the local machine and then have multiple
applications reference this common set of assemblies.
Please contact us at email@example.com if you would like us to build a more elaborate side-by-side solution designed for your needs.
aspnet20sample example contains an example project with an appropriate
HTTP module source code and ready to use binaries. Read more
about the example.
This solution can be used with existing ASP .Net applications including
precompiled and non-updateable. No changes to the application are required, only
webapp.config file needs to be created or modified.
To configure the example HTTP module to create a process default activation context for an application pool executing ASP .Net applications:
w3wp.exedoes not have an external manifest (
C:\WINDOWS\system32\inetsrv\w3wp.exe.manifestmust not exist).
webappwhich will make the manifest name
webapp.manifest(see note below).
binfolder. As stated above, you can write your own module or you can use the module provided in Manifest Maker examples:
C:\Program Files\Maze Computer\Manifest Maker\Examples\aspnet20sample\AspManifestHelpers\bin\Release\AspManifestHelpers.dll. Make sure to use the
Releasebuild as shown above.
<configuration>section find (or add) section
<httpModules>section add this entry (use your names, if you used your own module):
<add name="HttpModule_ProcessManifest" type="MazeComputer.AspManifestHelpers.HttpModule_ProcessManifest, AspManifestHelpers"/>
At this point ASP .Net will load the HTTP module and will call the
Init method during the module initialization. The module
provided with Manifest Maker creates the activation context and sets it as the
process default in this method. The activation context is
never released - process default activation context is only released when the
process terminates. In case multiple applications are configured to use the same
application pool and more then one of them uses this module, it ignores errors
resulting from attempts to set the process default activation context after it
has already been set.