Using the ASP.NET Runtime to Extend Desktop Applications with HTML Scripts
People often think of HTML as the sole domain for Web applications. But HTML's versatile display attributes are also very useful for handling data display of all sorts in desktop applications. The Visual Studio .NET start page is a good example. Coupled with a scripting/template mechanism you can build highly extendable applications that would be very difficult to build using standard Windows controls. In this article, Rick introduces how to host the ASP.NET runtime in desktop applications and utilize this technology in a completely client-side application using the Web Browser control.
by Rick Strahl
May 9, 2003
Page 1 of 4
he ASP.NET runtime in .NET provides the ability to create rich HTML content for your applications dynamically in your desktop applications. It also provides a powerful mechanism for extending the functionality of applications through script code.
A few issues back (CoDe Magazine, Nov/Dec 2002) I introduced the topic of dynamic code execution, which is not trivial in .NET. My article generated questions from CoDe readers about how to use this technology in more sophisticated applications. Most of the questions centered around the apparently intriguing topic of 'executing' script pages that use ASP-style syntax. My "Dynamically Executing Code in .NET" article was so long that I didn't have enough room to add an extensive example of how to apply this technology. I will do so this month by rehashing this subject as I show you another more powerful mechanism that's built into the .NET Framework to provide an ASP.NET-style scripting host for client applications.
Hosting the ASP.NET Runtime
Microsoft made the .NET Framework very flexible, especially in terms of the various sub-systems that make up the core system services. Did you know that you can host the ASP.NET scripting runtime in your own applications? This has several benefits over the ASP-style parsing approach I featured in my last article.
Microsoft ships the ASP.NET runtime in the .NET Framework and has made the ASP.NET runtime a system component so you don't have to install anything separately. The runtime is much more powerful than the simple script parser I previously introduced because the runtime supports just about everything that ASP.NET supports for Web pages including all installed and registered languages and ASP.NET-style Web Forms syntax. You can use the runtime to determine if you've previously compiled a page so you don't have to recompile it each time. The ASP.NET runtime handles updates to pages automatically, and as an especially nice bonus you can debug your script pages using the Visual Studio .NET debugger.
As always with .NET internals, though, this power comes with a priceoverhead and complexity. Visual Studio .NET offers a number of non-obvious ways to accomplish seemingly simple tasks, including passing parameters or leaving the runtime idle for a while. I'll introduce a set of classes that simplify this process down to a few lines of code. I'll also show you the key things that you need to know and implement.
You'll find that you can call the ASP.NET runtime from any .NET applications. Follow these three major steps:
1. Set up the runtime environment.
You'll tell the runtime which directory to use as its base directory for a Web application (like a virtual directory on a Web Server except here it will be all local files) and you'll set up a new AppDomain that the runtime can execute in.The ASP.NET runtime executes in another AppDomain and all information transmitted between your app and it run over the remoting features of .NET.
2. Create the script page.
You will create a single page that contains ASP.NET code. This means you can create pages that contain <% %>, <%= %>, and <script runat="server"> syntax as long as it runs in a single page. You also need to use the appropriate <@Assembly> and <@Namespace> inclusion tags. The script pages can access the current application directory and all assemblies accessible to the current app.
3. Call the script page to execute.
You need to tell the runtime which page to execute within the directory tree set up as a 'virtual' in the file system. ASP.NET requires this to find its base directory and associated files. To make the actual call you use the SimpleWorkerRequest class to create a Request object that you will pass to the HttpRuntime's ProcessRequest method.
Using the wwAspRuntimeHost Class
To simplify the process of hosting the ASP.NET runtime I created a class that wraps steps 1 and 3. Listing 1shows the code to run a single ASP.NET request from a disk-based script file.
You start by instantiating the runtime object and setting the physical disk path where you're hosting the ASP.NET applicationyou'll put scripts and other script content such as images into this same directory. The Start method launches the ASP.NET runtime in a new AppDomain. My class delegates this process to a Proxy class, AspRuntimeHostProxy, which actually performs all the work. My wwAspRuntimeHost class is simply a wrapper that has a reference to the proxy and manages this remote proxy instance by providing a cleaner class interface and error handling for problems remoting over AppDomain boundaries.
Once you've called the Start() method you can make one or more calls to ProcessRequest() with the name of the page to execute in the local directory you set up in cPhysicalPath. You can use any relative path to an ASP.NET page using syntax like "textRepeater.aspx" or "subdir\test.aspx." You can also pass an optional query string made up of key value pairs that the ASP.NET page can retrieve. My example serves as a simple though limited parameter mechanism. I'll discuss how to pass complex parameters later.
In order to generate output from a page request you need to specify an output file with a full path in the cOutputFile property. This file will receive any parsed output that the ASP.NET runtime has parsedin most cases the HTML result from your script. Although you'll typically generate HTML for display in some HTML rendering format like a Web browser or a Web Browser control (see Figure 1), you can generate output for anything. I often use templates for code and documentation generation that is not HTML.