Embedding Resources in ASP.NET 2.0 Assemblies - Part 2
page 1 of 1
Published: 22 May 2006
Unedited - Community Contributed
Abstract
In this article Mark examines how to embed resources in ASP.NET 2.0 Assemblies with the help of code samples.
by Mark Hines
Feedback
Average Rating: This article has not yet been rated.
Views (Total / Last 10 Days): 33438/ 64

Introduction

Using embedded resources with ASP.NET 2.0 has made deploying your server controls easier than ever.  First, we will address some issues that need clarification when using embedded resources.  Then, it will be time to leverage this power and its inherent flexibility to easily customize the look and feel of those controls for each of your sites.

Clarifications

1.      You can only embed resources in projects that have a dll as their ultimate output.  Thus, you cannot embed resources in your web project, unless you are using the new Web Application Project.

2.      Just because you have a rendered WebResourceUrl does not mean that the embedded resource was actually found.  Unfortunately, GetWebResourceUrl will return a URL whether it finds the embedded resource in your assembly or not.  You will not really know that it is not finding the embedded item, unless you are watching the HttpHeaders and see "404 Not Found" returned on the WebResource.axd requests when the item is not found.

3.      You must include the default namespace in the name reference to the embedded item.  This means that if your default namespace for the assembly is MyWebAppAssembly and your embedded item's name is MyImage.jpg, you must refer to it in both the AssemblyInfo and the code as "MyWebAppAssembly.MyImage.jpg."  (They are case sensitive, so watch that also.)

Embedding Resources in Embedded Resources

If you want to embed a resource that references other embedded resource (for example, images in a stylesheet), you need to add the PerformSubstitution tag to your AssemblyInfo.cs, as shown in Listing 1.  Then you can reference other embedded resources, as shown in Listing 2. 

Listing 1 - AssemblyInfo.cs entries

[assembly: WebResource("MyWebAppAssembly.MyStylesheet.css","text/css", PerformSubstitution = true)]
[assembly: WebResource("MyWebAppAssembly.MyImage.gif","img/gif")]
[assembly: WebResource("MyWebAppAssembly.MyComponent.htc","text/component")]

Listing 2 - MyStylesheet.css Snippet

.MyDiv { background-image: url('<% =WebResource("MyWebAppAssembly.MyImage.gif ") %>'); }

Aside: A colleague of mine was embedding a behavior for his server control and discovered that to get the .htc file to behave correctly he had to set the content type to text/component, as shown at the bottom of Listing 1.

Overriding Embedded Resources

Scenario: You have developed a really nice server control that provides a consistent look and feel for the applications that you developed and your latest client loves the functionality, but not the appearance.

Solution: Leverage the Type parameter passed to GetWebResourceUrl to provide skinning.  Listing 3 provides one example of how you could do this.  There is a lot going on in this listing, but it breaks down as follows:

1.      Load the type of the current assembly, which will be the default source for the embedded resources.

2.      Check for an overriding entry in the app's web.config.

3.      Parse out the base namespace of the assembly.

4.      Define the template for the stylesheet link and build the Web Resource URL.

5.      Combine the two things from step 4 and add the entry to the Page's Head tag area.

Listing 3 - Overriding Embedded Resources

private void LoadStylesheetLink()
{
  Type uiResourceType = this.GetType();
  string overrideType =ConfigurationManager.AppSettings[
   "MyWebAppAssembly.EmbeddedResourceType"];
  if (overrideType != null)
    uiResourceType = Type.GetType(overrideType);
  string assemblyName =uiResourceType.Assembly.FullName;
  string assemblyBaseName =assemblyName.Substring(0, assemblyName.IndexOf(","));
  string includeTemplate = "<linkrel='stylesheet' type='text/css' href='{0}' />";
  string webResourceUrl =thePage.ClientScript.GetWebResourceUrl(uiResourceType,
    assemblyBaseName +".MyStylesheet.css");
 ((System.Web.UI.HtmlControls.HtmlHead)thePage.Header).Controls.Add(new
   LiteralControl(String.Format(includeTemplate, webResourceUrl)));
}

Embedded Resource Locations

All of the examples that I have supplied presume that the embedded resource resides in the root of the assembly and would be compiled with the name format, MyWebAppAssembly.MyEmbeddedResource.  Your resources do not have to be in the root and can exist in any folder in the project, but you must remember that the name will change to MyWebAppAssembly.MyFolderHeirarchy.MyEmbeddedResource and all references to that resource will need to be changed as well, both in code and in the AssemblyInfo.

Embedded Resource Recommendations

The "this feels right" part of me says that all embedded resources should be located in the closest possible proximity to the control that consumes them.  The "minimum fuss" part of me says that any embedded resource that you plan to override should be stored in the root of the assembly.  So, I guess that it comes down to whether or not you are going to allow people who will be able to know the folder structure of your control assembly to override your embedded resources.  Also, I would consider long and hard whether or not to allow anyone to override anything other than the appearance elements of the control.  I do not feel comfortable allowing someone to override any embedded JavaScript that my control might reference.

Suggested Readings

Embedding Resources in ASP.NET 2.0 Assemblies - Part 1

Conclusion

Now, with a few clarifications and some new tricks, we are ready to develop skinnable, web server controls that should reduce our development time and improve client satisfaction, which is what we are really all about.



User Comments

Title: Great Article   
Name: Tuka
Date: 2009-07-22 4:26:13 AM
Comment:
Great article ! Thanks
Title: VB.NET   
Name: Jim
Date: 2008-07-17 6:44:03 AM
Comment:
Note that VB.Net ignores the folder portion of the resource path and you can therefore not have resources with the same name in different folders.
Title: Re: Stylesheet question   
Name: Mark
Date: 2008-01-24 7:18:45 AM
Comment:
Nisar,

You need to add the PerformSubstitution tag to your WebResource assembly attribute for the css file, ie:

[assembly: WebResource("MyWebAppAssembly.MyStylesheet.css","text/css", PerformSubstitution = true)]

Then it should work.
Title: Great article but one error   
Name: Oliver
Date: 2007-10-13 5:48:05 AM
Comment:
If you try to embed a htc-File, the correct content-type
is "text/x-component" and not "text/component".
Then it works!
Title: vs2005 designer doesn't support embedded resources   
Name: Sam
Date: 2007-09-06 12:07:49 AM
Comment:
I currently am building a control using several embedded resources. All of the resources work great in the code and on the browser, however it renders pretty ugly in the vs2005 designer.

My best guess is that vs2005 designer isn't rendering the the server tags in the css file. All of the other styles in the css file appear, but not my background-images that use embedded resources. Its really frustrating! If you know anything at all about that, that would be great.

I double checked that I could access the embedded images in the css file by including some img tags with them in them when in design mode. Those all come up! But the css does nothing... :(
Title: StyleSheet question   
Name: Nisar
Date: 2007-04-26 4:44:23 PM
Comment:
i have a question:

i tried doing something like this in Style.css
background-image: url('<%=WebResource("nmak.Web.UI.WebControls.ColumnComboBox.bg_header.gif")%>')

but no luck...
thats what you mean when you said ?

Listing 2 - MyStylesheet.css Snippet

.MyDiv { background-image: url('<% =WebResource("MyWebAppAssembly.MyImage.gif ") %>'); }

please let me know...
thanks
Title: Great work but need an example   
Name: Niraj
Date: 2007-03-26 5:04:57 AM
Comment:
Hi. This is great stuff from your side but i wanted to see a demo project in which you actually give reference to javascripts of a DLL
Title: Mr.   
Name: Andreas Möhlenbrock
Date: 2007-01-05 10:59:12 AM
Comment:
Great! Thank you very much!
Title: Mr.   
Name: Mark Kamoski
Date: 2006-06-01 9:58:05 AM
Comment:
Thank you VERY much for a great set of articles. I really appreciate it. Keep up the good work.

Product Spotlight
Product Spotlight 





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


©Copyright 1998-2017 ASPAlliance.com  |  Page Processed at 2017-03-25 11:28:01 PM  AspAlliance Recent Articles RSS Feed
About ASPAlliance | Newsgroups | Advertise | Authors | Email Lists | Feedback | Link To Us | Privacy | Search