Embedding Resources in ASP.NET 2.0 Assemblies
page 1 of 1
Published: 04 Oct 2005
Unedited - Community Contributed
Abstract
With 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.
by Mark Hines
Feedback
Average Rating: This article has not yet been rated.
Views (Total / Last 10 Days): 36787/ 33

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. 

Listing 1: AssemblyInfo.cs entries

[assembly: System.Web.UI.WebResource("myImage.gif", "img/gif")]
[assembly: System.Web.UI.WebResource("myStylesheet.css", "text/css")]
[assembly: System.Web.UI.WebResource("myJavascript.js", "text/js")]

Namespace Note

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.

Listing 2: Setting an image control’s source

Image theImage = new Image();
theImage.ImageUrl =
      Page.ClientScript.GetWebResourceUrl(this.GetType(), "myImage.gif");

Listing 3: Adding a stylesheet to the page header

string includeTemplate =
      "<link rel='stylesheet' text='text/css' href='{0}' />";
string includeLocation =
      Page.ClientScript.GetWebResourceUrl(this.GetType(), "myStylesheet _Links.css");
LiteralControl include =
      new LiteralControl(String.Format(includeTemplate, includeLocation));
((HtmlControls.HtmlHead) Page.Header).Controls.Add(include);

Listing 4: Rendering a javascript include

string scriptLocation =
      Page.ClientScript.GetWebResourceUrl(this.GetType(), "MSDWUC_WindowStatus.js");
Page.ClientScript.RegisterClientScriptInclude("MSDWUC_WindowStatus.js", scriptLocation);
 

ClientScriptManager Quirks

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!

Page.ClientScript.RegisterClientScriptResource(GetType(Me), "Namespace.Filename.js")

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:

Page.ClientScript.RegisterClientScriptResource(GetType(MyCustomCommonClass), "Namespace.Filename.js")

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: Pingback   
Name: Jeffrey's Blog
Date: 2010-08-09 3:58:44 AM
Comment:
Pingback from http://jeffreypaarhuis.wordpress.com/
Title: Thank you so much!   
Name: Nick Qu
Date: 2010-05-05 5:44:09 AM
Comment:
So nice post, and thank you so much!

I bumped in the same issue on such a code Page.ClientScript.GetWebResourceUrl(this.GetType(), "PMS_WP_ProjectBasicInfo.jqrLib.images.bar_on.png");

it returns a url, while this url shows nothing on the page.

There are 2 reasons.
1. for Sharepoint webpart, please retrieve current web url, then plus "/" and then plus this webResourceUrl.

2. for the embedded resources, like .js, .css, .png, please select them all in the visual studio file explorer, and in the property panel, click "Embeded Resource" (the default value is content).

Then everything would be OK.

Enjoy!



[assembly: System.Web.UI.WebResource("PMS_WP_ProjectBasicInfo.jqrLib.jquery-1.4.2.min.js", "text/javascript")]
[assembly: System.Web.UI.WebResource("PMS_WP_ProjectBasicInfo.jqrLib.jquery-ui.min.js", "text/javascript")]
[assembly: System.Web.UI.WebResource("PMS_WP_ProjectBasicInfo.jqrLib.jquery-ui.css","text/css")]
[assembly: System.Web.UI.WebResource("PMS_WP_ProjectBasicInfo.jqrLib.c_leftPanel.css", "text/css")]
[assembly: System.Web.UI.WebResource("PMS_WP_ProjectBasicInfo.jqrLib.images.bar.png","image/png")]
[assembly: System.Web.UI.WebResource("PMS_WP_ProjectBasicInfo.jqrLib.images.bar_on.png", "image/png")]


http://shsrv15/ProjectDatabase/WebResource.axd?d=HD5PdFjzCY4yVMlX0Ect79twBGjEzg7va08TtHM7LFib95EUaGsi0iTewnlQrJCPiD8HJzvC9iuD8gbciMvZeqyLTkEqGOgdTu8Y4xzva01V0HaVGD3m84KTvEai4m9hXdTQUz3EQD7khvdsyDlRmw2&t=634086770435545656
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: Deals365.us Coupon Codes || Deals365.us Coupons || Deals365.us Promotional Codes   
Name: Balu
Date: 2009-07-10 9:44:09 AM
Comment:
BMC Photo Art : The best source for the Coupons, Promotion Coupon Codes, Online Discount Codes, Promo Codes, Promotions and Discounts. Providing this Coupons, Discount Codes Promo Codes you can save lot of money. We have thousands of Coupons, Discount Offers for hundreds of online stores, so you can always find the Deals, Coupons, Promo Codes, Discounts, Promotions and Promotional Coupon Codes. More information: http://www.freecoupons4you.com
Title: app_themes   
Name: Thomas
Date: 2009-07-02 2:46:12 PM
Comment:
Any ideas on using the .css'es as part of app_themes?
Title: Thank you so much   
Name: Eliana M. López
Date: 2009-03-11 10:29:07 AM
Comment:
It was really helpfull, i can solve my problem.
I really thank you.
Title: Thanks   
Name: Tom Pester
Date: 2009-01-22 8:50:31 AM
Comment:
Thanks for this very good article
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: CSS lessoS   
Name: :-:S€ZæR - >
Date: 2008-05-03 7:20:54 AM
Comment:
CSS "Cascading Style Sheets" LessoNs - WeB DesigN LessoN - - Web site : http://WWW.css-lessons.ucoz.com/index.html
Title: Embedding Resources in ASP.NET 2.0 Assemblies   
Name: Rajeesh Kuthuparakkal
Date: 2008-02-24 11:02:06 PM
Comment:
Excellent!!!!!!!!!!!111
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: Edit Resource before use?   
Name: Kalpesh
Date: 2007-07-30 4:19:34 AM
Comment:
Can we edit resource before use?
Title: RE: need help   
Name: Ghaus
Date: 2007-07-02 9:36:41 AM
Comment:
I fugered out what was my problem... The images i've trying to show, has an invalid header (gif images with wrong gif header), thats why only firefox open it.

the webResources works fine

Thanks
Title: need help   
Name: Ghaus
Date: 2007-06-29 7:31:44 PM
Comment:
I made a control that use WebResources to hold a couple of images/gif and a script.js...

It works fine on FireFox, it shows the .gif and reference to the correct javascript, but in IE it show en empty image but it loads the correct javascript... so what's wrong??? I don't know.

i.e.:
http://localhost/Net/WebResource.axd?d=veyh26mLkFgI176lX5PP6xGUMaBSRPeC8Th1I-AFbm6ktUhSl9zDrBBNjSk-MVLF0&t=633185582466250000

In firefox opens an image but in ie shows an empty image.

Sorry for my english
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?

Thank you.
Title: mr   
Name: Lee
Date: 2006-11-28 8:48:58 AM
Comment:
Excellent article it has helped me alot thank you!
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.
Title: error in   
Name: Dee Veloper
Date: 2006-09-10 3:15:52 PM
Comment:
"Page.Clientscript" does not compile in assembly

is there a clearly written example somewhere that works ?????
Title: Write out text or variabel in Embedded resouce?   
Name: MartinF
Date: 2006-08-12 11:54:08 AM
Comment:
Hello,

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'"?
Title: webresource name   
Name: Alex
Date: 2006-06-02 3:47:10 AM
Comment:
Yhe correct webresource name format is:

[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.

I've added the "assembly" settings in "AssemblyInfo.cs":
[assembly: System.Web.UI.WebResource("arrowUp.JPG", "image/jpeg")]
I also tried:
[assembly: System.Web.UI.WebResource("arrowUp.JPG", "img/jpg")]
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.
Title: Nothing rendering!   
Name: na
Date: 2005-12-24 9:54:54 PM
Comment:
Please help! I have copied every code snippet on the Internet implementing WebResources and none of them work!

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).

Any help would be great!


[assembly: WebResource("image1.jpg", "image/jpeg")]
[assembly: WebResource("help.htm", "text/html")]
namespace TestLibrary
{
public class TestControl : Control
{
// Create a new Image control.
Image _img = new Image();
_img.ImageUrl = this.Page.ClientScript.GetWebResourceUrl(typeof(TestControl), "image1.jpg");
this.Controls.Add(_img);

// Create a new HtmlAnchor control linking to help.htm.
HtmlAnchor a = new HtmlAnchor();
a.HRef = this.Page.ClientScript.GetWebResourceUrl(typeof(TestControl), "help.htm");
a.InnerText = "help link";
this.Controls.Add(a);

}
}
}
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?

Product Spotlight
Product Spotlight 





Community Advice: ASP | SQL | XML | Regular Expressions | Windows


©Copyright 1998-2024 ASPAlliance.com  |  Page Processed at 2024-03-19 6:37:05 AM  AspAlliance Recent Articles RSS Feed
About ASPAlliance | Newsgroups | Advertise | Authors | Email Lists | Feedback | Link To Us | Privacy | Search