AbstractWith ASP.NET version 2.0, it has become a snap for server control authors to embed image and script resources into assemblies, making deployment clean and error-free. Mark Hines shows you how, and notes a few pitfalls of which to be aware.

Average Rating: This article has not yet been rated.Views (Total / Last 10 Days):135293/
329

One of the greatest difficulties when developing common web controls (either server or user controls) that we’ve come across in our development group is how to deal with client-side scripts and images. In ASP.NET 1.1 we have recently started using an HttpModule and compiled resource files, but ASP.NET 2.0 makes it much easier to manage embedding resources in assemblies.

The Problem

During your development of robust, rich-client web applications, you’ll quickly develop a set of controls that use JavaScript to provide your application’s users with a really pleasant experience. Now, you have to figure out what to do with these controls. Do you create user controls and cut and paste them between your web applications, or do you create custom server controls that compile nicely and are easy to share? Once you tackle that decision, you have to figure out what you’re going to do with the JavaScript. If you embed it in the user control, it has to travel over the wire every time the page is requested, which will negatively impact any low-bandwidth users of the web application. If you make it a server control, then you have to create an installation script or somehow manage the distribution and location of the external files across all applications using the control.

The ASP.NET 1.1 Solution

To avoid these issues in ASP.NET 1.1, you could create an HttpModule or HttpHandler that responded to your own key filename. This HttpModule or HttpHandler would then return the appropriate resource that had been compiled into a specific resource assembly. In this case, you had to manage the HttpModule or HttpHandler, make sure it was referenced correctly in the web.config, make sure that the compiled resource was available, and cross your fingers and hope for the best. While this is a solution to the problem described above, it is still a lot of work.

The ASP.NET 2.0 Solution

The new version of ASP.NET has integrated the 1.1 solution, and now we get to reap the rewards. So, you can just embed your resources in the appropriate assemblies and reference them without having to worry about configuration or deployment issues. The necessary process is described in the following sections.

Embedding the Resource

To make the file or image accessible from your server control’s assembly, simply add the file to your project, go to the Properties pane, and set the Build Action to Embedded Resource. To expose the file to a web request, you need to add code like that shown in Listing 1 to your AssemblyInfo.cs file. These entries expose the embedded resource so that the ClientScriptManager can both get to the file and know what kind of file it is.

The project’s default namespace (defined in the Application tab of the project's Properties page) will be added as a prefix to the filename of embedded resources. In this case, I’ve set the default namespace to an empty string. Otherwise, the tag’s first parameter would need to be DefaultNamespace.Filename.Extension instead of simply Filename.Extension. (This was the biggest pitfall I encountered because it wasn’t obvious that the namespace would be added as a prefix, and so I was referencing the resources by their short names when I should have been using the long format.)

Accessing the Embedded Resource

To add the embedded resource to our ASP.NET page, we will be calling the ClientScriptManager’s GetWebResourceUrl method. Its first parameter is the Type of the control’s class (which will eventually provide .NET with an assembly reference where the embedded resource is contained) and its second parameter is the name of the resource as specified in the AssemblyInfo.cs file. For example, to load an image in an Image control, use the code in Listing 2. To add a stylesheet to the Page header area, use the code in Listing 3. To render a JavaScript include tag, use the code in Listing 4.

One of the things I encountered when working with this technique was that most examples of server controls do their “thing” during the Render event. So, I attempted to be a good corporate citizen and have my controls behave the same way and I found that I could not use RegisterClientScriptBlock at this point in the page life cycle. RegisterStartupScript seemed to work fine in this scenario and IE 6.0 apparently tolerates rendering styles at this point and applying them to the page’s rendered contents, but I wasn’t happy with that. So, I discovered that I had to make all calls to RegisterClientScriptBlock on or before the OnPreRender event for them to be added to the correct part of the page.

Conclusion

We’ve covered how you can embed resources in your server control projects and how to reference them in a web environment. This should simplify your life from a deployment perspective, and should make your server controls tighter now that they can leverage static images and files, and do not require any installation other than deployment of the compiled assembly.

User Comments

Title:
e
Name:
a
Date:
2012-08-09 5:43:40 PM
Comment: asdf

Title:
Great Article
Name:
NightOwl888
Date:
2010-10-06 3:26:16 PM
Comment: Great article - it took me awhile to figure out the CSS includes because script manager doesn't have built in support for CSS.

However, I found a better way to include the .js files - there is no need to use .GetWebResourceUrl!

Another tip: if you have many controls in a single solution and would rather just serve up 1 JS file regardless of what controls are on the form, use a common object instead of Me for all of the controls in the solution:

The framework uses the object type to determine if the .js file has already been output, so it will automatically prevent it from happening twice. Minimizing server requests is key for high performance, and serving fewer files is key for minimizing server requests.

Title:
Asembly Name not Namespace
Name:
Rob
Date:
2010-01-31 3:37:40 AM
Comment: There is a stack of comments on this topic generalyl that suggest that the resource names need to be prefixed with the assembly name not the namespace....Since many progs use the same name for both, this only shows up if you have a difference....

Title:
Hi
Name:
abc
Date:
2009-10-22 5:12:04 AM
Comment: Good one!!

Title:
Fab!
Name:
Marc Borel
Date:
2009-10-15 7:43:00 AM
Comment: Brilliant, just what I was looking for, this has saved me a lot of head-scratching, when I tried to have an embedded .gif file in an ASP.Net Custom Control.Merci !

Title:
How can we embed word document in assembly?
Name:
caci
Date:
2009-09-22 10:47:02 AM
Comment: I want to embed doc file in the Resources Assembly so that I don't have to copy template file while deploying. The dlls should take care of these. Then I should be able to get this document object at run time.

Title:
this.GetType() or this.GetType().BaseType
Name:
fan of waqu
Date:
2008-08-21 9:44:39 AM
Comment: This solved my problem --- this is very easy to overlook, and most examples that I came across don't address it. I wasted most of a day trying to figure why my image wouldn't render, but this was the problem.

Mad props to waqu for pointing this out.

Title:
this.GetType() or this.GetType().BaseType
Name:
waqu
Date:
2008-06-12 7:08:12 AM
Comment: If you get issues with this.GetType() then it might be because you are trying to get the resource within the main project. Make sure that this.GetType().Namespace will return your project name space and not 'ASP'. In that case, try using this.GetType().BaseType.

Title:
GetType()
Name:
Dave Myers
Date:
2007-12-05 12:13:43 PM
Comment: I have been successfully embedding resources when the (client script include) from my control library, but was having a booger of a time embedding them from my UI...the url returned from GetWebResourceUrl was always wrong. Turns out that if you are using an external assembly, using this.gettype() will point to the wrong assembly....so i had to use externallibrary.somecontrolinlibrary.gettype(). I don't like having to point to a control in my external library so the url will generate correctly...but that seems to work

Title:
Resources located in a different assembly
Name:
Alfero
Date:
2007-12-03 8:02:03 PM
Comment: I have to place some javascript resources in an assembly that will be referenced by several controls. Is there a way to access these resources as it appears I can not do it this way. I keep getting a 404 error.

Title:
It's good for custom control
Name:
Lev
Date:
2007-11-09 3:20:50 PM
Comment: Great post, I use the same technique for embedding resources into CUSTOM CONTROL, but does anybody know how to embed resources into USER CONTROL?

Thanks,Lev

Title:
good post
Name:
Salman
Date:
2007-10-17 7:18:28 AM
Comment: Can anyone tell me how to get a resource URL from an satellite assembly. i have implemented the .NET framework 1.1 way to implement it i have built the satellite assembly using the resgen and then AL tool. now i am referring resources in my project using the reflection method and using resource manager. is there any way to get resource URL using the resource manager.

please help me if someone can please reply me on salmaan_khaan@hotmail.com

Title:
brilliant explanation
Name:
Jeroen
Date:
2007-08-27 4:32:16 AM
Comment: I wanted to find out how to implement this, came across this article, and it couldn't be explained in an easyer way

Title:
THANK YOU
Name:
Alex
Date:
2007-04-17 6:31:47 AM
Comment: I've spent the whole day working on Asp Server Control trying to embed default ImageUrl value. I fell into the same trap as I think you did: referencing image file names without appending default name space.

Thank you so much for this article.

Alex.

Title:
Control into control
Name:
Anna
Date:
2007-04-05 3:07:10 PM
Comment: I have a question:I have two xontrols that are using WebResources. The are located in different files.When on my page I put one control to another, the inner control cannot find the embedded resource files.Is there way around?

Title:
Build Action does not appear
Name:
dh
Date:
2006-09-29 8:01:16 AM
Comment: I am having the same problem as mentioned by several others below. I have an asp.net web site, and I am trying to add a javascript file as an embedded resource. When I view the properties for the .js file, I do not see the Advanced Properties, so I cannot set the Build Action to embedded resource.

you tell how to write out the url for another embedded resource inside an embedded resource but what if i want to simply write out some text or a variabel inside a embedded resource ?

My problem is that i have created a custom control for a radio button where it is possible to show a picture instead of the radio button. It have 2 states which is unchecked and checked state.Soo what i do is that i simply write the url to the pictures when creating the control, and then i need the urls to be written out in my embedded css (stylesheet) file, but i cant find out how to do it.

Hope anyone can help

Thanks

Martin

Title:
i got it to work
Name:
mario
Date:
2006-07-21 2:24:35 AM
Comment: nice job! it works! tnx again

Title:
It does not work with the final version of VS 2005
Name:
Tadeusz Dracz
Date:
2006-06-15 7:02:20 AM
Comment: Thanks to Mark Chipman for the working solution!

Title:
Is that a typo?
Name:
Skipper
Date:
2006-06-08 2:55:20 PM
Comment: Should "text='text/css'" be "type='text/css'"?

[DefaultNamespace].[Resources Folder].[Resource File Name].[Resource File Name Extension]while [DefaultNamespace] should be empty if you haven't set default namespace, and [Resources Folder] should be empty if your resource files are located at the root of the project.

Title:
Build Action to Embedded Resource missing
Name:
Vlad Pitaru
Date:
2006-05-29 2:23:49 AM
Comment: Yep, I have the same problem! There is no Build Action: Embedded in web projects.

How can we workaground?

Title:
RE: Build Action to Embedded Resource
Name:
Mark Hines
Date:
2006-04-04 9:59:45 AM
Comment: Apparently, with the restructure of web projects and the compilation pattern, you can't embed resources in a web project. You can in other compiled projects though.

Title:
Build Action to Embedded Resource
Name:
J Castillo
Date:
2006-04-03 12:19:31 PM
Comment: I also can't see the settings for Build Action to Embedded Resource in the property sheet of my 2005 solution. Is this because my Solution is a "Web Site Solution"? I have a .txt file that I would like to "embed" as a resource but my properties sheet does not show the "advanced" info for me to select it. Any ideas?

Title:
RE: Build Action to Embedded Resource
Name:
Mark Hines
Date:
2006-03-20 9:44:22 AM
Comment: Setting the Build Action is done on the individual items (graphics, scripts, etc.) and should be an option in the Advanced section of the Properties tab for that item.

Title:
Build Action to Embedded Resource
Name:
Malcolm Rasool
Date:
2006-03-20 7:50:50 AM
Comment: I just can't seem to be able to see the settings Build Action to Embedded Resource in the property sheet of my 2005 solution. Do you know how to restore it? I would love to implement the piece of code you discussed in your article however I'm stuck at this point. I can't even find any reference to this problem anywhere on the net.

Title:
Images refs in embeded css
Name:
Lars
Date:
2006-02-22 5:00:17 AM
Comment: I have an embeded css style sheet that references some picures that is also embeded. Can this be done?

Title:
A better example of how to do this I believe
Name:
Mark Chipman
Date:
2006-02-16 2:44:44 AM
Comment: I hope that this link will help somebody out who is having difficulties with this:

http://www.codeproject.com/aspnet/MyWebResourceProj.asp

-Mark Chipman

Title:
Any Updates????
Name:
Duane Haworth
Date:
2006-02-02 12:39:11 PM
Comment: I can't get my JPG image to appear and this has been the best site I've found to explain how to do this in ASP.NET. Unfortunately, I can't get this to work.

I get no errors, just an empty image control.

Build Action on image is set to "Embedded Resource".ImageURL is set in the "OnPreRender" event.imgArrow.ImageUrl = Page.ClientScript.GetWebResourceUrl(this.GetType(), "arrowDown.JPG");I've used Reflector to verify my namespace.

Title:
Re: Nothing rendering!
Name:
Mark Hines
Date:
2005-12-27 7:41:45 AM
Comment: First, I would verify that the Build Action on your WebResources is set to Compiled Resource. If that's set correctly, I would recommend checking the compiled dll with Reflector to verify that the namespace of the compiled resource is what you think it is.

I am able to get WebResource Urls just fine, but downloading/viewing/rendering the urls all return nothing - not even an Error!

Here are some of my code snippets I am using (these were copied from an MSDN article and it doesnt work!) When I deploy this control on a webpage, I get a broken image and a link that returns an empty page. I know the resources are setup correctly because if I change the Help.htm name in the GetWebResourceUrl() call, then browse to the generated URL, I get an exception. If I leave it as you see it below, I get a valid, but blank page (no exception).

Title:
js not rendering
Name:
andres
Date:
2005-11-28 5:54:36 PM
Comment: hello, i tried all of these, but my javascript include is not rendering at all. i manage to get the scriptLocation, though. i place the "Page.ClientScript.RegisterClientScriptInclude" in the "RenderContents" method, is that okay?

Title:
Does it works in final vs 2005 release?
Name:
Anatoly
Date:
2005-11-19 2:07:55 AM
Comment: It seems to me I having a problem to apply css file in vs2005 final.controls doesn't get style sheet that them should.Any ideas?