views:

1671

answers:

3

In my web application I include all of my JavaScripts as js files that are embedded resources in the assembly, and add them to the page using ClientScriptManager.GetWebResourceUrl(). However, in some of my js files, I have references to other static assets like image urls. I would like to make those assembly resources as well. Is there a way to tokenize the reference to the resource? e.g.

this.drophint = document.createElement('img');
this.drophint.src = '/_layouts/images/dragdrophint.gif';

Could become something like:

this.drophint = document.createElement('img');
this.drophint.src = '{resource:assembly.location.dragdrophint.gif}';
+2  A: 

I'd suggest that you emit the web resources as a dynamic javascript associative array.

Server side code:

StringBuilder script = new StringBuilder();
script.Append("var imgResources = {};");
script.AppendFormat("imgResources['{0}'] = '{1}';", 
    "drophint", 
    Page.ClientScript.GetWebResourceUrl(Page.GetType(), "assembly.location.dragdrophint.gif"));
script.AppendFormat("imgResources['{0}'] = '{1}';", 
    "anotherimg", 
    Page.ClientScript.GetWebResourceUrl(Page.GetType(), "assembly.location.anotherimg.gif"));

Page.ClientScript.RegisterClientScriptBlock(
    Page.GetType(),
    "imgResources",
    script.ToString(), 
    true);

Then your client side code looks like this:

this.drophint = document.createElement('img');
this.drophint.src = imgResources['drophint'];
this.anotherimg = document.createElement('img');
this.anotherimg.src = imgResources['anotherimg'];

Hope this helps.

Jon
+2  A: 

I don't particularly care for the exact implementation @Jon suggests, but the idea behind it is sound and I would concur that emitting these would be a good thing to do.

A slightly better implementation, though this is all subjective to some degree, would be to create a server-side model (read: C# class(es)) that represents this dictionary (or simply use an instance of Dictionary<string, string>) and serialize that to JavaScript literal object notation. That way you are not dealing with the string hacking you see in Jon's example (if that bothers you).

Jason Bunting
+2  A: 

I concur with Jason's assessment of the initial solution I proposed, it can definitely be improved. My solution represents an older school javascript mentality (read, pre the emergence of ajax and json). There are always better ways to solve a problem, which one of the reasons why stackoverflow is so cool. Collectively we are better at the craft of programming than anyone of us on our own.

Based on Jason's ideas I'd revise my initial code, and revise some of what Jason suggested. Implement a C# class with two properties, the img resource "id" and a property that contains the WebResourceUrl. Then, where I differ some from Jason is that rather than using a Dictionary I'd propose using a List, which you can then in turn serialize to JSON (using DataContractJsonSerializer), and emit the JSON as the dynamic script, rather than manually generating the javascript using a string buider.

Why a List? I think you may find that dictionaries when serialized to json, at least using the DataContractJsonSerializer (fyi available with the 3.5 framework only, with the 2.0 or 3.0 framework you'd need to bolt on aspnet ajax and use is json serializer), are a little more cumbersome to work with than how a list would serialize. Although that is subjective.

There are implications too with your client side code. Now on the client side you'll have an array of the json serialized MyImageResourceClass instances. You'd need to iterate through this array creating your "img" tags as you go.

Hopefully these ideas and suggestions can help get you going! And no doubt there are other solutions. I'm interested to see what comes of this.

Jon