I wanted to put together some code examples for a website that also included examples of the code working. Rather than create a new .aspx file for each example, I wanted an easier way to create the working examples. JMH pointed me to the VirtualPathProvider as a means of achieving this.
Many examples that I looked at were a little over complicated to get a grasp of the basic concept, so I came up with the code below as an example of how I got it to work.
Obviously, this example can be built on to include caching of the pages, updating of the code etc. but I just wanted to share this example for starters. Once I play around with it a bit more, I'll try and post updates and improvements
It's also written in C#, so will try and convert it to VB when I have 5 minutes.
myVirtualProvider.cs
The virtual path provider is registered in global.asax Application_Start. Many examples I saw use AppInitialize in the class but this didn't seem to work for me.Code:using System; using System.Collections; using System.Collections.Generic; using System.Data; using System.Security.Permissions; using System.Web; using System.Web.Hosting; using System.IO; //the following 2 namespaces are from my own app. You can point to any DAL or BLL namespaces you have in your //own app using w3d.App.BLL.Globals; using w3d.App.BLL.Codes; namespace w3d.App.BLL.myVP { public class myVirtualProvider : VirtualPathProvider { //checks if the current url folder starts with our designated "virtual" folder private bool IsPathVirtual(string virtualPath) { String checkPath = VirtualPathUtility.ToAppRelative(virtualPath); return checkPath.StartsWith("~/virtual".ToLower().ToString(), StringComparison.InvariantCultureIgnoreCase); } //MUST OVERRIDE function checks if the file exists in your virtual file system //Many web examples use a cache to store the virtual files for faster access //in which case you'd have to check for the key value in the cache public override bool FileExists(string virtualPath) { if (IsPathVirtual(virtualPath)) { //checks if the virtual file exists in my codes object. This calls a function that //queries the db with the value held in virtualPath. //Assuming the path to your virtual file was www.domain.com/virtualFolder/virtualFile.aspx //then virtualPath would contain /virtualFolder/virtualFile.aspx if (codes.CheckIfFileExists(virtualPath)) return true; else return false; } else { return Previous.FileExists(virtualPath); } } //MUST OVERRIDE function retrieves the file from the virtual file system as a new virtualfile object public override VirtualFile GetFile(string virtualPath) { myVirtualFile file = new myVirtualFile(virtualPath); if(file.fileContent == null){ return Previous.GetFile(virtualPath); }else{ return file; } } //default constructor for the Virtual Path Provider public myVirtualProvider() : base() { // // TODO: Add constructor logic here // } } #region "myVirtualFile" //Virtual file object inherits from VirtualFile public class myVirtualFile : VirtualFile { //String property to contain the code to be streamed public string fileContent; //default Constructor for the Virtual File Object. Populates code string public myVirtualFile(string VirPath) : base(VirPath) { //retrieves the code text from a function in my codes object fileContent = codes.GetCodes(VirPath); } //MUST OVERRIDE. Streams the code string to a Stream object. public override Stream Open() { Stream stream = new MemoryStream(); if (fileContent != null || fileContent.Equals(String.Empty)) { // Put the page content on the stream. StreamWriter writer = new StreamWriter(stream); writer.Write(fileContent); writer.Flush(); stream.Seek(0, SeekOrigin.Begin); } return stream; } } #endregion }
global.asax
That's basically the virtualpathprovider setup. You also need to add the virtual folder into your directory hierarchy. In my case I just added a folder called virtual in the webroot.Code:. . <%@ImportNamespace="w3d.App.BLL.myVP" %> <%@ImportNamespace="System.Web.Hosting" %> . . Sub Application_Start(ByVal sender AsObject, ByVal e As EventArgs) ' Code that runs on application startup HostingEnvironment.RegisterVirtualPathProvider(New myVirtualProvider()) EndSub
My database was setup like this (this is in MySQL)
Obviously code contains the data to stream and code_file contains the virtualPath value to check against.Code:coderef INT autoincrement title VARCHAR (255) just used as link text in a datalist of all the code examples code longtext code_file VARCHAR (30)
I have only tested this with inpage coding so far, not code behind. You also need to make sure any links to physical files in your site include ~/ at the beginning. This includes any master pages etc.
You can also stream master pages, user controls and html files.
Hope that helps. I will post any updates I have and once I have a more complicated example, with caching, directories etc. then I'll post that as an Advanced Example.
I am currently working on creating a siteMapNode for the file for my web.sitemap hierarchy. I have written another example on adding siteMapNodes dynamically, which is located here....Adding dynamic SiteMapNode to SiteMap when using VirtualPathProvider



LinkBack URL
About LinkBacks
Reply With Quote

Bookmarks