Virtual path provider in ASP.Net 2.0 is a way to make the world believe that something exists on the server which in reality is not. This enables the web application to retrieve resources from a virtual file system. This allows file systems containing browsable resources to be virtualized.
The virtual file system, including the folder and file hierarchy, is maintained in any source except for the file system. This alternate file system can be SQL Server or Zipped file or in obfuscated format. However, ASP.Net does not restrict using Windows File System, if somebody wants to use it.
Virtual file system can contain any file in the web application other than
- Files in special folder such as App_Data and so on
All the above mentioned resources are loaded by asp.net before the virtual path provider and hence cannot be inside the virtual file system.
Moreover, if the site is precompiled, the content inside the virtual file system (the content provided by the virtualpathprovider) is not compiled
Creating a custom VirtualPathProvider
Why do we need a custom virtual path provider? Well, we need that to specify how to relate your virtual file with the request. Custom VirtualPathProvider is to convert the request from the user for the Virtual File and convert that to a request that can be understood by ASP.Net.
In the attached sample, I’m using text files as my source for asp.net markup and these files are placed inside the App_Code folder instead of the regular folder. To add little complexity around that, I’m creating the ASP.Net markup by replacing the placeholders specified in the text file with a valid asp.net markup.
In a real scenario, you might want to get his information from a database or some other place instead of a text file. Microsoft Office SharePoint uses this approach to store all the contents inside a Microsoft SQL Server instance.
First and foremost, we need to create a class by deriving the base
VirtualPathProvider base class implements several methods but is not tailor made for any situation. So we’ll have to override the methods that will fetch the required data for us, process the data (if required) and pass on this processed markup to the ASP.Net.
public class TextVirtualPathProvider : VirtualPathProvider
public static void AppInitialize()
public override bool FileExists( string virtualPath )
public override VirtualFile GetFile( string virtualPath )
In the code above,
TextVirtualPathProvider is inheriting from
VirtualPathProvider and overriding two methods
GetFile() and defines a custom logic for processing
AppInitialize() is a special method. This is kind of
Main() for the
VirtualPathProvider and is invoked before anything else in this class.
Typically, this method registers this
VirtualPathProvider with the ASP.Net Compilation system to specify an alternate execution path.
This method is not mandatory in all the CustomVirtualPathProviders. We can even specify the same code inside the
Application_Start() even inside Global.asax file.
One more important method is the
GetFile() method. This method returns a
VirtualFile type. This method is invoked by the ASP.Net engine to get the markup for the virtual file.
The next step in creating the custom provider is to create a class that derives
VirtualFile class that knows what exactly should be done for the virtual file request.
public class TextFile : VirtualFile
public TextFile( string virtualPath, TextVirtualPathProvider provider )
: base( virtualPath )
public override Stream Open()
This class is pretty straightforward aswell, a constructor and an override method.
The constructor has to have virtualPath to initialize the base class object, the virtualpathprovider is provided to get any additional information and is purely optional.
ASP.Net engine, when obtained the handle to this object invokes the
Open() method to get the stream containing the markup. So,
Open() is the main method in the entire code that should understand the virtual file system and how to respond to any virtual file request.
This is fairly useful functionality in ASP.Net 2.0. Some of the very straight forward implementations of this would be to provide tiny urls for the requests. Instead of a request like http://www.myserver.com/articles.aspx?id=10, we can have http://www.myserver.com/articles/VirtualPathProvider.aspx which is not present physically, but fetched from the database. A more complex implementation would be that of a SharePoint portal sort of application.