views:

295

answers:

2

Hi,

Assuming the code below:

public class DynamicAspxHandler : IHttpHandler {
    bool IHttpHandler.IsReusable { get { return false; } }

    void IHttpHandler.ProcessRequest(HttpContext httpContext) {
        string aspxContent = PlainASPXContent();
        Page page = CreatePage(httpContext, aspxContent);
        page.ProcessRequest(httpContext);
    }

    Page CreatePage(HttpContext context, string aspxContent) {
        // How to implement this?
    }
}

how can I implement CreatePage method to instantiate a page based on the plain string content of ASPX?

The note is that the ASPX string itself can containt reference to already existing MasterPage on the disk.

I realise there must be huge performance issue with this but at this stage I just want to know how I can do that. Obviously I will have to cache the result.

Thanks.

+6  A: 

The path you're trying to go down is essentially loading ASPX files from some other storage mechanism than the web server file system. You've started to implement part of that, but you actually don't even need a custom HttpHandler to do this - ASP.NET has an existing mechanism for specifying other sources of the actual ASPX markup.

It's called a VirtualPathProvider, and it lets you swap out the default functionality for loading the files from disk with, say, loading them from SQL Server or wherever else makes sense. Then you can take advantage of all the built-in compiling and caching that ASP.NET uses on its own.

The core of the functionality comes in the GetFile method and the VirtualFile's Open():

public override VirtualFile GetFile(string virtualPath)
{
    //lookup ASPX markup
    return new MyVirtualFile(aspxMarkup);
}

//...

public class MyVirtualFile : VirtualFile
{
    private string markup;

    public MyVirtualFile(string markup)
    {
        this.markup = markup;
    }

    public override Stream Open()
    {
        return new StringReader(this.markup);
    }
}

Note that today, using a custom VirtualPathProvider does require full trust. However, soon ASP.NET 4.0 will be available and it supports VPPs under medium trust.

Rex M
Sounds very good! Thanks. I found a sample for ASP.NET MVC here: http://padcom13.blogspot.com/2009/04/virtualpathprovider-example.html
Dmytrii Nagirniak
+1  A: 

One way of doing it is by creating a subclass of VirtualPathProvider and set it as the HostingEnvironment.VirtualPathProvider by calling HostingEnvironment.RegisterVirtualPathProvider. You will have to override a few methods. The most important being GetFile(). The build system will take care of caching.

Gonzalo