Teun.ToString()

by Teun Duynstee [Macaw]

<August 2008>
SuMoTuWeThFrSa
272829303112
3456789
10111213141516
17181920212223
24252627282930
31123456


Navigation

Subscriptions

News

I discontinued this blog. I now post at: www.TeunToString.net



Download Finch PocketBlogger

Post Categories

Article Categories



VirtualPathProvider adventures: trying to get XInclude to work on web.config files

Disclaimer: this is all tested on Beta 1 code.

When I had the VirtualPathProvider sample from Scott Guthrie working, I wanted to create something useful with this technique. The idea I had was building XInclude support for web.config files. This would allow to split up the several segments of a config file over several physical files. Some ConfigurationSectionHandlers offer some support for reading values from external files (like NameValueFileSectionHandler), but often, this support is not sufficient.

What I would like to do is splitting web.config into parts that are the sole responsibility of the development team (and which are automatically deployed with newer versions) and parts that are the domain and responsibility of the system administrators. The web.config should then be constructed before it was even read by the AppDomain. I figured that by using the VirtualPathProvider model, I could just subclass from the default provider (called MapPathBasedVirtualPathProvider) and change it only for the cases where the GetFile method is called for files that are called web.config. Only in those cases, I would then open the file myself, scan it for any xi:include elements and replace them by the content they refer to. Easy. So I thought.

First, it turns out that MapPathBasedVirtualPathProvider is an internal class, so no subclassing. No harm done: when our provider is initialized, the system passes us the existing provider to allow us to do some delegation to it. So, to start up I built a wrapper class that delegates all of its calls to the previous provider. Code now looks like this:

 public class ConfigPathProvider : VirtualPathProvider
 {
  protected VirtualPathProvider _previous = null;
  public ConfigPathProvider(){}

  // The system initializes our provider after we have registered it
  public override void Initialize(VirtualPathProvider previous)
  {
   _previous = previous;
  }

  public override bool DirectoryExists(string virtualDir)
  {
   return _previous.DirectoryExists(virtualDir);
  }

  public override bool FileExists(string virtualPath)
  {
   return _previous.FileExists(virtualPath);
  }

  public override VirtualDirectory GetDirectory(string virtualDir)
  {
   return _previous.GetDirectory(virtualDir);
  }

  public override VirtualFile GetFile(string virtualPath)
  {
   return _previous.GetFile(virtualPath);
  }

  /* And some more methods, you get the point */

}

The AppInitialize is set up in a different class, to allow this class to be in a reusable library. Putting up break points on all of the methods now allows us to see how this works. Some findings:

  • web.config is not accessed through the provider (boohoo, this immediately kills my mini-project)
  • not all of the other file requests go through the provider anyway. This is because we delegate to the MapPathBasedVirtualPathProvider. It turns out that the GetDirectory method returns an instance of MapPathBasedVirtualDirectory. When ASP.NET iterates through the files or directories within that directory, the MapPathBasedVirtualDirectory will return MapPathBasedVirtualFile instances that will directly access the filesystem without using the VirtualPathProvider to instantiate the VirtualFile instance. This is a bug, because it breaks the concept of delegating to the previous provider (MSFT: if you are reading this: the problem is in MapPathBasedVirtualPathEnumerator.Current)

 

Wrapping it up: VirtualPathProviders can be used for serving code and aspx templates from a custom source, like a database. It will not work for images and other resources that are not mapped to ASP.NET, but it will also not work for the web.config file. This is a pity, because that seemed like a promising application. I think that the debugging experience with code being served from the database may be very special as well. ;)

 

posted on Tuesday, February 15, 2005 1:32 PM by TeunD





Powered by Dot Net Junkies, by Telligent Systems