Friday, October 12, 2007

WebResource.axd or how I learned to love the embedded resource

It all started with my own library, a dll in which I wanted to include Javascript, CSS and ultimately images or flash files. I did it the only way I could in 1.1, mainly adding the resources to the project, setting them as Embedded Resource, then reading them and either put them in the page or write them in the application directory and link them in the page. As you can imagine, there were a lot of issues related to writing writes and so on.

But then .NET 2.0 and the AjaxControlToolkit arrived. This toolkit had this funny looking Tab thing, and it used images. So where did it get the images? I was surprised to see that the namespace of the TabContainer control was decorated with stuff like this:

[assembly: WebResource("", "image/gif")]

then in the CSS files, stuff like


Could it be so easy? yes! And for the js files, they had this class called a ScriptControlBase and the only thing you needed to do to insert a javascript file was decorate the implementing class like this:

[ClientScriptResource("AjaxControlToolkit.TabPanel", "AjaxControlToolkit.Tabs.Tabs.js")]

But what was the underlying mechanism? Googling for WebResource.axd you get these informative links:
Using WebResource.axd for embedded resources
Accessing Embedded Resources through a URL using WebResource.axd

Working with Web Resources in ASP.NET 2.0

These three articles pretty much explain the basics, so I won't do anything but emphasize the more important points:
  • When you use the name of the resource, either when decorating the namespace or when getting the reference to it, use the project namespace and the folder in which the file is in, otherwise it will not work. So if you have the namespace MyControls.Web and you have the folder Images in which you embedded an Image.gif file, the name should be MyControls.Web.Images.Image.gif.
  • To programatically get the url for an embedded resource use Page.ClientScript.GetWebResourceUrl(Type type,string resourceName)
  • In order to get the contents of an embedded resource use code like this:
    Assembly assembly = GetType().Assembly;
    arr = assembly.GetManifestResourceNames();
    foreach (string name in arr)
    if (name==resourceName) {
    Stream s = assembly.GetManifestResourceStream(name);
    // do something with the stream

But what is this WebResource.axd? It's an IHttpHandler, one that you can also implement quite easily. They are used to handle Ajax, file uploads, get access to all kinds of resources. Look it up. Somewhere in the near future I might write an article about these, too.