One nice feature that ASP.NET added in the 2.0 feature set was the ability to embed resources directly within an assembly and then later extract them through a separate Http Handler. You've notably saw this by all the WebResource.axd calls. If you're building a ASP.NET MVC view, you have two ways of extracting web resource urls.
Way 1
If you are using the default view engine, all of your views should derive either from ViewPage or ViewUserControl, which ultimately has access to ClientScript.WebResourceUrl, etc. This method is the easiest to use as it doesn't require anything special:
<script src="<%= ClientScript.WebResourceUrl(typeof(Foo), "Foo.Bar.js") %>" type="text/javascript">
</script>
This way works great, as I said if you're using the WebFormsViewEngine and you're within the view itself. However sometimes you have a controller action or other html helper extension methods that are rendering HTML directly ... or you're just using a completely different view engine. At this point, you don't have access to ClientScript.
Way 2
The second way is by having your own extension method that will generate the web resource url for you. This way, you can get a web resource url anywhere you have an instance of your HtmlHelper object.
1: public static class HtmlHelperExtensions
2: {
3: private static MethodInfo getWebResourceUrlMethod;
4: private static object getWebResourceUrlLock = new object();
5:
6: public static string WebResourceUrl<T>(this HtmlHelper htmlHelper, string resourceName)
7: {
8: if (string.IsNullOrEmpty(resourceName)
9: throw new ArgumentNullException("resourceName");
10:
11: if (getWebResourceUrlMethod == null)
12: {
13: lock (getWebResourceUrlLock)
14: {
15: if (getWebResourceUrlMethod == null)
16: {
17: getWebResourceUrlMethod = typeof(AssemblyResourceLoader).GetMethod(
18: "GetWebResourceUrlInternal",
19: BindingFlags.NonPublic | BindingFlags.Static);
20: }
21: }
22: }
23:
24: return "/" + (string) getWebResourceUrlMethod.Invoke(null,
25: new object[] { Assembly.GetAssembly(typeof(T)), resourceName, false });
26: }
27: }
And that's it. Now, in your code you can get a web resource url very similarly as with ClientScript:
<script src="<%= Html.WebResourceUrl<Foo>("Foo.Bar.js") %>" type="text/javascript">
</script>
What I don't like about this approach is that it is using reflection to invoke the private method, but considering these methods are not exposed anywhere (ohh, and you cannot create an instance of ClientScriptManager) this is the only approach that can be taken. Furthermore, remember this is an ASP.NET feature, and works very nicely within the MVC framework. The url, WebResource.axd, is mapped to the AssemblyResourceLoader Http Handler which is independent of the ASP.NET web forms runtime. Hope this helps some people!
03084bb9-4e05-4b4b-a793-8377e21d2a04|1|5.0