What?
I started reading Programming Microsoft ASP.NET 2.0 Applications: Advanced Topics
again recently and
ran across something in Dino's book that was piqued my interest. ASP.NET 2.0 comes built with this concept of the Virtual Path Provider.
The virtual path provider system is a method of raising the layer of abstraction when it comes to ASP.NET and the file system. In ASP.NET 1.1 System.IO was used directly
by ASP.NET to access the file system. In 2.0 it works through the MapPathBasedVirtualPathProvider class. That class, in turn, uses the MapPathBasedVirtualFile class to access
the files through System.IO.FileStream. This is not significant, of course, unless they
allow you to hook into this provider model and take over the process...which they do.
This virtual path provider system is primarily driven by three abstract classes in the System.Web.Hosting namespace,
VirtualPathProvider,
VirtualFile, and
VirtualDirectory. ASP.NET 2.0 has implementations of these in the same namespace,
MapPathBasedVirtualPathProvider, MapPathBasedVirtualFile, and MapPathBasedVirtualDirectory. I do not see any documentation on these on MSDN, but they aren't too hard to find with
Reflector. To those familiar with ASP.NET "MapPath" should remind you of Server.MapPath,
something you can use if you need the physical location of a file and all you have is the virtual path. The MapPathBasedVirtualPathProvider and its helpers do the "MapPath" work for
ASP.NET, fetching the physical files for processing.
What extending your application with a custom implementation of the VirtualPathProvider gives you is the ability to change how that works, allowing you to access the file system differently,
or more likely, allowing you to look anywhere you choose for the content you need to fulfill the page request. This feature was, according to Dino, added for the Sharepoint team. Sharepoint
stores quite a bit of content in Sql Server (so I understand...I haven't used it much myself), so creating this allows them (or anyone else) to pull pages not from the file system but from
anywhere. You could get your aspx files from Sql Server, you could pull them from a zip file, you could construct them from .txt files (not that that would be a good idea), you could get them
by calling a web service (though surely only the insane would do this), or whatever. The sky (or more accurately, the full capabilities of the .NET framework) is the limit.
Why and When?
So this is cool, but does it have any practical application? I think it does. Take, for example, how Community Server "archives" posts. For our example we will look at the last post on
the North Dallas .NET User Group blog aggregator. You can find it
here.
Note the "archive/2007/04/02/Telligent-Internship-Program.aspx" page. If you were to hack their servers and check their file system, you would find that those directories and that .aspx file do
not exist. They create these "fake" pages through url rewriting. You are not really seeing that aspx page; you are seeing data served up from Sql Server. This is a great method for avoiding
something like "http://cs.nddnug.net/blogs/postviewer.aspx?id=789452798", which is similar to how I am currently showing posts on this blog (but not for long). The url is not very informative
and it is also not (from what I hear) search-engine friendly. So they use url rewriting to make you and search engine crawlers everywhere think that there are really pages there.
I have not seen anybody mention this as a possible application for extending the virtual path provider model, but it totally makes sense to me. That seems like exactly what it was made for.
Community Server would not be using it because this feature was added in ASP.NET 2.0. This would explain why every method I have seen of doing something like this uses url rewriting. But should
we be doing something else now that ASP.NET 2.0 is out?
Example
At the bottom is a link to download a sample that implements this. There are three important pieces. First, included is a script for creating a "Posts" table and filling it with some data.
To run the sample you will need to create a database and run the script. Second is a web application project that has the basic web code called "VirtualPathProviderTest". Third is a class
libary called VirtualPathProviderLib.
VirtualPathProviderTest: There are three files of significance. First is the web.config. Change the connection string to point to your own database. Second is the MasterPage, which
has the repeater that will list the posts. Third is the Global.asax. This latter file is the only one that is truly pertinent to the implementation. In Application_Start the custom
VirtualPathProvider is registered. Doing this is simple enough (it only takes two lines), but is necessary.
VirtualPathProviderLib: There are several files in this library that are there simply for the sake of making the example functional (Post.cs, PostCollection.cs, and Data.cs). The
actual implementation of the logic for the virtual path provider system are found in CustomPathProvider.cs and CustomVirtualFile.cs.
I annotated the code in various places to explain why certain things are done the way they are. I hope you find that helpful.
Other Resources
The only other resource than the class library documentation on MSDN that I found particularly helpful was an article on MSDN,
Virtualizing Access to Content: Serving Your Web Site from a ZIP File.
Downloads
Source