Building ASP.NET AJAX Controls (Pt 8 - Embedding Resources)

Links to the other posts in this series

In Part 7 we looked at how to wrap our client components into a server control that renders the markup and script required to deliver the UI and behaviours we want. Take a look at this page to see the control in action in a ListView template bound to a simple database query. The last thing I wanted to do was embed some resources in the control assembly so we can remove the reference to the "loose" component script and we can also incorporate a custom icon image.Picture3

Firstly, any resource we want to use:

  1. has to be embedded in our assembly
  2. has to be enabled for access via the WebResource attribute.

To embed a resource in the assembly, add it to the project and set its Build Action (in Properties) to "Embedded Resource".

The WebResource attribute is only valid on assembly declarations and enables specific resources in the assembly for use as web resources. It takes the form WebResourceAttribute(string webResource, string contentType) so we would use something like the following to enable access to an embedded version of our component script.

 [assembly: WebResource("ServerControls.VEMapControl.js", "application/x-javascript")]

Then for the embedded script, we need to make a change to the GetScriptReferences() method to return the embedded script rather than the "loose" version:

 //yield return new ScriptReference("/Launch/JavaScript/VEMapControl.js");
yield return new ScriptReference("ServerControls.VEMapControl.js", "ServerControls");

I'd suggest leaving the loose version in there (commented out as above) at least for testing as you'll find you get a better debugging experience on the loose script so you'll probably end up switching back and forth for a while.

That should be all you need to do in order to embed the component script in the assembly. Things follow a similar pattern for the custom icon.Picture2

Add the icon file (in this case Houses.png) to the project and again set the Build Action to Embedded Resource.

We need to make some changes to the component implementation to make this work. In VEMapControl.js add an icon property to allow us to set the URL for the custom icon. Then in the initialize() function, set the custom icon for the pushpin using:

 this._shape.SetCustomIcon(this.get_icon());

In the server control code, we again need to expose the icon file as a web resource (note the path in the WebResource string):

 [assembly: WebResource("ServerControls.Images.House.png", "image/png")]

Then finally, set the icon property on the component in GetScriptDescriptors() to point to the embedded image resource:

 scd.AddProperty("icon",  Page.ClientScript.GetWebResourceUrl(typeof(ServerControls.VEMapControl), "ServerControls.Images.House.png")); 

GetWebResourceUrl() returns a URL reference to the embedded assembly resource. Something like "/WebSite1/WebResource.axd?d=xIJJb_tMCfFU621BrJxVLRFBJcRWpkJhjb_z5Khn1z2xQqHN2PQ5xrpT2ksxrt5Z0&t=633432448993801595" which will return the embedded House.png image. scd.AddProperty() ensures the component icon property is set before we call SetCustomIcon() .

That, I think, is about the end of the road. I've tried to include as much detail as is practical and hopefully you've found it useful. Don't hesitate to leave a comment of drop me a mail if anything's not clear. The source code (might be slightly out of date) is currently available here as part of my launch demos. You'll find it in the ServerControls project.

Technorati Tags: asp.net,ajax,virtual earth