Besides calling new Page()... , you can directly call the base implementation. Put this code in some static class:
public static string GetWebResourceUrl(this Assembly assembly, string name) { if (GetWebResourceUrlInternal == null) GetWebResourceUrlInternal = (Func<Assembly,string,bool,bool,System.Web.UI.ScriptManager,string>) typeof(System.Web.Handlers.AssemblyResourceLoader) .GetMethod("GetWebResourceUrlInternal", BindingFlags.NonPublic|BindingFlags.Static, null, new[]{typeof(Assembly),typeof(string),typeof(bool),typeof(bool),typeof(System.Web.UI.ScriptManager)}, null) .CreateDelegate(typeof(Func<Assembly,string,bool,bool,System.Web.UI.ScriptManager,string>)); return GetWebResourceUrlInternal(assembly, name, false, false, null); } volatile static Func<Assembly,string,bool,bool,System.Web.UI.ScriptManager,string> GetWebResourceUrlInternal = null;
And in Razor mode or in code it is used:
typeof(SomeClassInTheSameAssembly).Assembly.GetWebResourceUrl("Namespace.Resource.xxx")
Of course, using WebResource URLs in Razor views is not very useful. Instead, it is recommended that you place the resource in the Content or Scripts folder of your MVC application directly.
But the situation changes if you want to write HtmlHelper functions in shared class libraries that cannot put content in the target project.
Justification
This approach basically avoids creating a new, bulky Page object with every call to GetWebResourceUrl .
Looking at the source code , it turns out that the Page and ScriptManager contexts are easy to use. Therefore, calling AssemblyResourceLoader.GetWebResourceUrlInternal will directly hit the nail on the head. All you need to create a working WebResource.axd URL is Assembly and, of course, the name of the resource .
The disadvantage is that this function is internal, so it must be caused by reflection. However, the aforementioned implementation avoids the overhead of a function call by reflection every time. Instead, CreateDelegate used once to get a regular delegate that can be called with almost no overhead.
A race condition is assumed when accessing the GetWebResourceUrlInternal field. This does not do much harm, because it is very unlikely that this piece of code will encounter many parallel threads on the first call, and even if this happens, the result is still reliable.