How To: Dynamically Load A Page For Processing

I have often desired the ability to dynamically load a page for processing, much like we do for .asxc controls with LoadControl(pathToASCX).  For example, I may want to create a custom HTTP handler or module to dynamically load a page - while allowing me to programmatically change key properties before processing.  Here is a method that accomplishes such a task:

public static void LoadPage(string pagePath)
{
    // get the compiled type of referenced path
    Type type = BuildManager.GetCompiledType(pagePath);

    // if type is null, could not determine page type
    if (type == null)
        throw new ApplicationException("Page " + pagePath + " not found");

    // cast page object (could also cast an interface instance as well)
    // in this example, ASP220Page is a custom base page
    ASP220Page pageView = (ASP220Page)Activator.CreateInstance(type);

    // call page title
    pageView.Title = "Dynamically loaded page...";
    // call custom property of ASP220Page
    pageView.InternalControls.Add(
        new LiteralControl("<hr />Served dynamically...</hr />"));            

    // process the request with updated object
    ((IHttpHandler)pageView).ProcessRequest(HttpContext.Current);
}

20 Comments

  • Can you have the page (.aspx) and the code beside file (.aspx.cs) to be loaded dynamically or you have to have both in 1 file?... thanks.

  • Yes... this method works regardless of where the code resides. It also functions regardless of using Master pages or not. In my example, I just had to make sure that the code-behind file inherited from my custom base page - ASP220Page.

  • My test failed. It complained about the Label control it couldn't find. the .aspx contained a single LAbel that was assigned a value from .aspx.cs file. I also was testing in a normal website project, not WAP. Any ideas?

  • I am sorry, ignore my last message - I am too tired to think straight. It was an error I caused.
    Thanks for the great tip.

  • What's the advantage of this over a user control ??

  • Details: while testing, I saw that the file has to be in the virtual folder on one of its sub-folders (since BuildManager.GetCompiledType() accepts only virtual path). IS there a way to load conent out of the virtual directory of the webapp?
    Thanks

  • Dee,

    This really only makes sense when serving completely dynamic content. This may be from a custom HTTP handler or module.

  • Sean,

    You are correct. In this implementation, the page must exist in the web site. There is another tip/trick on how to pull off another way, and I will blog about it sometime this month.

  • This is a great piece of code. The only problem that I have is that if property such as Title is already being set by the code behind or master page It will override any setting that I pass to the PageView object. So any munipulation I can do gets wiped out once ((IHttpHandler)pageView).ProcessRequest(HttpContext.Current) gets called. Any help with this would be greatly appreciated. I am trying to use this as a way to send to mock data to pages for Test Driven Development.

    Thanks, Mike

  • mike,

    Unfortunately, last modification wins. The events that fire in the page will override your intitial value (as you have discovered)

    To allow your assignment to Title to succeed, you would probably need to create a helper property or method on the base page that would manage the rules of which change wins.

  • Palermo: Thanks for your response. I was able to put logic in the base class detects when there is a mock data source uses that data instead..

  • Did you ever figure out how to load conent out of the virtual directory of the webapp since BuildManager.GetCompiledType() accepts only virtual path? I want to have a separate project for running tests against the web project. These tests will be executed by NUnit so it's better to have them in a separate assembly.
    Thanks,
    Mike

  • Anyone on this thread know of an alternative to BuildManager.GetCompiledType() that while allow me to programmatically load a page for processing from a separate assembly? This assembly will contain automated tests against the web project in the same solution. I need to be able to access the properties of the page and it's master page.. including server controls and their state. Currently I can do this inside of the web project but not in a separate assembly.

    Thanks,
    Mike

  • Sean: I founded. :)
    Look at System.Web.UI.PageParser.GetCompiledPageInstance(string virtualPath, string absolutePath, HttpContext context). :)

    You can pass as virtualPath any string like "/page_name.aspx", as absolutePath a path to aspx file everywhere on hdd and current context. It works. :)

  • compiledType = BuildManager.GetCompiledType(virtualPath);
    if (compiledType == null)
    {
    object page = BuildManager.CreateInstanceFromVirtualPath(virtualPath, typeof(System.Web.UI.Page));
    compiledType = page.GetType();
    }

  • How can we get the controls of the dynamically loaded page ?

  • nice article..

  • I have the same question as Kunal. I have an Admin page and would like to read the controls from another .aspx page.

  • Thanks Palermo!

    @Kunal:
    in the case above you would do the following:

    foreach (Control control in ((Page)pageView).Controls)
    control. .....

  • Another question ...

    what exactly does the following do:
    ((IHttpHandler)pageView).ProcessRequest(HttpContext.Current);

    is this the same as a page redirect?

Comments have been disabled for this content.