AspAlliance.com LogoASPAlliance: Articles, reviews, and samples for .NET Developers
URL:
http://aspalliance.com/articleViewer.aspx?aId=850&pId=-1
Embedding Resources in ASP.NET 2.0 Assemblies - Part 2
page
by Mark Hines
Feedback
Average Rating: This article has not yet been rated.
Views (Total / Last 10 Days): 16717/ 20

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.


Product Spotlight
Product Spotlight 

©Copyright 1998-2024 ASPAlliance.com  |  Page Processed at 2024-04-25 10:48:29 PM  AspAlliance Recent Articles RSS Feed
About ASPAlliance | Newsgroups | Advertise | Authors | Email Lists | Feedback | Link To Us | Privacy | Search