Accessing Embedded Resources through a URL using
By Scott Mitchell
Prior to ASP.NET 2.0, such external resources that needed to be accessible to the visitor's browser had to be implemented as
actual files on the file system. If you've worked with ASP.NET 1.x's validation controls, your pages have included a reference
/aspnet_client/system_web/version/WebUIValidation.js and there is an actual file
with that name residing in the web application's root. Such external resources hamper deployment - if you deploy your
application from the testing server to production, it's imperative that the production server have the same external resources
WebUIValidation.js, in this case), in the same locations in the file system.
To remedy this, ASP.NET 2.0 allows for external resources to be embedded within the control's assembly and then be accessed
deployment is a breeze, as all of the resources are now contained within the assembly (the
There are no external resources whose file names and location on the file system must map up. Once embedded into the assembly,
these resources can be accessed from an ASP.NET 2.0 web page through a special URL (
In this article we'll examine how to embed external resources into an assembly and how to retrieve these resources on the web page using a special URL. This technique helps simplify installation and deployment for creating custom, compiled server controls that are shipped to customers. Read on to learn more!
A Insanely Contrived Custom Control Example...
To examine the embedded resources feature in ASP.NET 2.0, we need to build a custom control that includes external resources. For this article, I've decided to create a very simple control that extends the base functionality of the TextBox Web control and adds a rather psychedelic twist to it. This custom control - FunkyTextBox - is configured such that its client-side
onkeypressevent the TextBox's background color is changed to a randomly selected color defined in an array. The net result is that as the user types in text into the TextBox, it cascades through a series of different background colors, causing the user to say things like, "Grooooovy, man," and "Whoooooaaaaa."
This behavior requires a bit of client-side script: first, we need to add a function that picks a random number and assigns the
TextBox's background color accordingly; second, we need to define the array of possible colors. We could, very easily,
statements, namespace, and some of the 256 colors defined in the array have been removed for brevity):
This server control derived from the built-in ASP.NET TextBox control, but extends it in two ways. First, in the
a client-side attribute is added to the rendered
<input> tag so that whenever a key is pressed when the user's
ChangeBackgroundColor is invoked, passing in the
textbox reference. Second, in the FunkyTextBox's
is squirted directly into the page through the
In particular, the
ChangeBackgroundColor function and
funkyTextBoxColors array are defined. The
ChangeBackgroundColor function picks a random number and then assigns the passed-in HTML element's background color
to the matching background color defined in the
When the FunkyTextBox is added to an ASP.NET page, the resulting page markup contains the following:
OnPreRender method and the FunkyTextBox has been rendered into
<input type="text"> with its
onkeypress event invoking the
the browser will cache this external script file so that it only needs to be downloaded once (rather than with each page visit/postback,
Embedding an External Resource in the Control's Assembly
To embed a resource in your control's assembly, start by adding the resource to the server control project in Visual Studio. (At the end of this article you'll find the complete code available for download, which includes the FunkyTextBox Web control Project and a test website.) For FunkyTextBox, I've added a file named
Once the resource has been added to the project, select it from the Solution Explorer and then go to the Properties window. There, set the file's Build Action to "Embedded Resource", as shown below:
Once this selection has been made, when you build the solution the file will be embedded within the resulting assembly.
Accessing the Embedded Assembly through a URL
Resources embedded within an assembly can be accessed through the
WebResource.axdHTTP Handler. It can be accessed through a URL like
http://yoursite/WebResource.axd?d=assemblyKey&t=dateTimeOfLastAssemblyWrite, where assemblyKey is an encrypted string that encodes the name of the assembly that contains the resource to access, while dateTimeOfLastAssemblyWrite represents the time of the last assembly modification. Given a valid assemblyKey, the
WebResource.axdHTTP Handler returns the embedded resource content as its output.
WebResource.axd HTTP Handler to serve embedded assemblies involves three challenges:
- Marking an embedded resource as being accessible through the
- Determining the precise querystring values to pass the
WebResource.axdHTTP Handler to retrieve a particular embedded resource, and
- Including the URL generated in step 2 in the appropriate places within the ASP.NET page
WebResource.axdHTTP Handler. To override this default behavior and indicate that a resource can be accessed, we need to add an attribute to the server control project's
AssemblyInfofile. In particular, we need to add a
WebResourceattribute, like so:
Note: If you are using Visual Basic, use the less than and greater than characters to delimit the attribute, like:
<assembly: WebResource(...)>. Note that to see this file, you have to choose the "Show All Files" option
in Solution Explorer - it then appears underneath the "My Project" folder. Also, the
WebResource attribute is found
System.Web.UI namespace, so you may need to add a
using System.Web.UI; statement at the top
Imports System.Web.UI in VB).
The webResource parameter specifies the name of the resource, and should be named using the following pattern:
RootNamespace.PathToFile. For our example, the root namespace is
FunkyTextBox; since the resource file
is in the project's root directory, the PathToFile is simply
Funky.js. (If, however, it was in a folder named
Scripts, the PathToFile value would be
Scripts.Funky.js.) Therefore, the value to use for the
webResource parameter is:
The contentType parameter specifies the MIME type of the requested resource. When requesting an external resource, the browser
is making a separate HTTP request to the web server. The MIME type instructs the browser of the type of data being sent back.
registry managed by the Internet Assigned Numbers Authority (IANA) for an official list of MIME types.
Finally, the performSubstitution is an optional Boolean value that specifies whether the requested resource should be
The script might need to make reference to the embedded images resources. This can be done using the syntax
If such substitutions need to be made, set performSubstitution to True.
For our control, we can register the
Funky.js embedded resource using the following attribute declaration:
With the resource registered as being accessible through the
WebResource.axd HTTP Handler, all that remains is
to write the code that will generate the appropriate URL for the embedded resource. To accomplish this, we use the
GetWebResourceUrl(type, webResource) method.
For resources embedded within the control's assembly, pass in the control's type as the type parameter and the webResource
value used in the
WebResource attribute as the second parameter. For example, to get the URL to access the
Funky.js embedded resource
from the server control's code, we'd use:
by using the
in conjunction with the
GetWebResourceUrl method in the FunkyTextBox control's
OnPreRender method, like so:
With this new
OnPreRender method, the control adds the following rendered markup to the page:
WebResource.aspx HTTP Handler, which
grabs the embedded information and sends it back to the client.
In this article we saw how to embed resources within the assembly of a custom ASP.NET server control and then how to access those embedded resources remotely through a URL. This technique, which is new to ASP.NET 2.0, enables control developers to bundle external resources within the assembly, which simplifies packaging and deploying the server control.