Isolating ASP .Net Applications: Example | how-to | home |
As ASP .Net initializes its environment, it loads
configured HTTP modules.
We add our own HTTP module to this list and when ASP .Net calls our Init
method we create the process default activation context and do not register any
handlers - we do not want to be called again. Normally the Init method is only
called in an application, but if multiple applications are configured to use the
same application pool and they try to set the process default activation
context, all subsequent calls will fail. We detect the situation when the
CreateActCtx() API fails because the context is already set and we ignore this
error. It may be a good idea to crash the application instead of masking the
error if you want to enforce a clean and well-defined environment with only one
application per application pool.
C:\Program Files\Maze Computer\Manifest Maker\Examples\aspnet20sample.
This is an ASP .Net 2.0 class library and an example web application.
The HTTP module is implemented in the HttpModule_ProcessManifest
class. The Init method is:
// ----------------------------------------------------------------------
// Create the 'process-default' activation context
// ----------------------------------------------------------------------
public void Init(HttpApplication application)
{
// NOTE: We do not hook any events, no need to. Once we set the process
// -default activation context our job is done.
string path = AppDomain.CurrentDomain.BaseDirectory;
string file = Path.Combine(path, "webapp.manifest");
UInt32 dwError = 0;
bool bOK = ActivationContextHelper.CreateProcessContext(file, AppDomain.CurrentDomain.BaseDirectory, out dwError);
// This is an error and we must make sure it does not go unnoticed
if (!bOK && ActivationContextHelper.ERROR_SXS_PROCESS_DEFAULT_ALREADY_SET != dwError)
{
string err = string.Format("HttpModule_ProcessManifest.Init: Cannot create process-default win32 sxs context, error={0} manifest={1} url={2}",
dwError, file, application.Context.Request.Url);
System.Diagnostics.Trace.WriteLine(err, "HttpModule_ProcessManifest");
ApplicationException ex = new ApplicationException(err);
throw ex;
}
if (application.Context.IsDebuggingEnabled)
{
string state = (bOK) ? "Activation context created." : "Activation context already existed.";
string msg = string.Format("{0}; Init; manifest={1}; {2}", System.DateTime.Now.ToString(), file, state);
System.Diagnostics.Trace.WriteLine(msg, "HttpModule_ProcessManifest");
}
}
The ActivationContextHelper
class performs the activation context
creation. The manifest file name is hard-coded as webapp.manifest
, but
there is no reason why it could not be different or somehow configured. Your web.config
file should look somewhat like this:
<?xml version="1.0"?> <configuration> <system.web> <httpModules> <add name="HttpModule_ProcessManifest" type="MazeComputer.AspManifestHelpers.HttpModule_ProcessManifest, AspManifestHelpers"/> </httpModules> </system.web> </configuration>
Of course there may be other settings, we only included here entries relevant to this particular case.
This example is not dependent on IIS6 because it does not use any functionality specific to IIS6. On Windows XP it works both in IIS5 and in the Visual Studio 2005 development server. However the development web server installed with Visual Studio 2008 has an embedded manifest and cannot be used in this manner unless you modify the executable and remove the embedded manifest resource.
To run the example open the project (aspnet20sample.sln) using Microsoft
Visual Studio 2005. First set the DropInManifest
as the startup project
then run the project. Your will get output similar to this:
Press this button to run the test:
Label
Now click the button. The text "Label" changes resulting in:
Press this button to run the test:
C:\Program Files\Maze Computer\Manifest Maker\Examples\aspnet20sample\DropInManifest\aspnet.sample.assembly\sampleDLL.dll
The DLL was loaded from the private assembly and the COM object was successfully accessed.
Attention: The development web server used by Visual Studio 2005 has an external manifest file (WebDev.WebServer.exe.manifest) which contains only a reference to Common Controls 6. You need to rename that file to test this solution using this web server. The development web server used by Visual Studio 2008 has an embedded manifest resource and cannot be used unless you remove the resource from the .EXE.
To verify that this is really working as expected, remove the above HTTP
module from web.config
and run the project
again (make sure to first stop the Visual Studio 2005 web server).
This time you get the familiar error message:
If webapp.manifest
does not exist in the web application directory, the HTTP module throws an exception:
Read more: