14

Marked a javascript file as "Embedded resource"
Added WebResource attribute to my AssemblyInfo class

Now i'm trying to output the embedded javascript to my master page. All I'm getting is a "Web Resource not found" from the web resource url.


Project Assembly Name:

CompanyProduct


Project Default Namespace:

Company.Product.Web


Javascript file located:
Library/navigation.js


AssemblyInfo:

[assembly: WebResource("CompanyProduct.Library.navigation.js", "text/javascript")]


Code in master page:

Page.ClientScript.RegisterClientScriptInclude("NavigationScript", Page.ClientScript.GetWebResourceUrl(this.GetType(), "CompanyProduct.Library.navigation.js"));

Server Error in '/' Application.

The resource cannot be found.

Description: HTTP 404. The resource you are looking for (or one of its dependencies) could have been removed, had its name changed, or is temporarily unavailable.  Please review the following URL and make sure that it is spelled correctly.

Requested URL: /WebResource.axd
Version Information: Microsoft .NET Framework Version:2.0.50727.1433; ASP.NET Version:2.0.50727.1433
Naeem Sarfraz
  • 7,360
  • 5
  • 37
  • 63
  • Is your app running on multiple servers (web farm, load balanced or similar)..? – KristoferA Dec 01 '08 at 16:51
  • Using Red Gate's .NET Reflector I can see the resource is named "Company.Product.Web.Library.navigation.js" One other thing, my code in the master page is contained within the OnPreRender function for the master page. Any other tips? – Naeem Sarfraz Jan 15 '10 at 08:32
  • I really would like to get this resolved.. – Naeem Sarfraz Feb 20 '10 at 08:42

15 Answers15

14

Instead of this.GetType(), get a type from the assembly that contains the resource.. ie:

typeof(Company.Product.Web.Library.Class1)

Does that work?

abatishchev
  • 98,240
  • 88
  • 296
  • 433
meandmycode
  • 17,067
  • 9
  • 48
  • 42
  • Nope, cos there is no Class1 defined in the Library folder. It's an embedded javascript file I'm try to get at. – Naeem Sarfraz Feb 20 '10 at 08:35
  • Clearly you misunderstand the problem, the 'Class1' was just an example of a class name, you should pick whatever you want from that library, the important thing is you provide the method call a type that is from the SAME assembly as where the embed attribute is.. – meandmycode Feb 20 '10 at 20:48
  • Apologies. I'm working within the same project. I can see the path using reflector but no joy getting it out as described in my question. – Naeem Sarfraz Feb 26 '10 at 21:00
4

Came to the same issue today. The problem seems to be that AssemblyResourceLoader uses the assembly containing the type provided to GetWebResourceUrl method (first parameter) which in your case is a dynamically created assembly for the master page (.master) and does not contain the resource you are looking for. I assume that your resource file is included in the same assembly as your base master page (.master.cs file) then you could use typeof to get the Type instance

Page.ClientScript.RegisterClientScriptInclude(
   "NavigationScript",
   Page.ClientScript.GetWebResourceUrl(
      typeof(MyMasterPage),
      "CompanyProduct.Library.navigation.js"));

where MyMasterPage is the name of your master page

Looks like it is also possible to use any other type declared in the same assembly where the resource is embedded.

dh.
  • 1,501
  • 10
  • 9
3

I think you want the full paths to be based on the namespace, not the assembly; So anywhere you have "CompanyProduct.Library.navigation.js", replace it with "Company.Product.Web.Library.navigation.js". Also, there is a method Page.ClientScript.RegisterClientScriptResource() that does what you need in one method (as opposed to using RegisterClientScriptInclude(GetWebResourceUrl()).

Chris Shaffer
  • 32,199
  • 5
  • 49
  • 61
  • 1
    Agreed with your first comment. Using Reflector I can see that my embedded javascript is `Company.Product.Web.Library.navigation.js`. Although using `RegisterClientScriptResource ` didn't seem to make a difference, still getting the error. – Naeem Sarfraz Feb 20 '10 at 08:39
1

Just had this problem and solved it based upon meandmycode's response; however, maybe a more detail explanation is needed.

When you register the script block using the ScriptManager.RegisterClientScriptInclude method the "type" parameter must be of a class inside the same project as the .js script. If you have no class associated with the script block you are going to just have to pick another class.

Mark Dornian
  • 318
  • 4
  • 9
1

I had a similar problem and, in my case, it was caused by the fact that Page.ClientScript.GetWebResourceUrl resourceName parameter is case sensitive.

Guish
  • 4,968
  • 1
  • 37
  • 39
  • Is there somewhere this is documented? I have been looking for over an hour to find it, but can't. I was stuck in webresource hell this morning... – Zack Feb 12 '15 at 15:16
  • Not really documented (maybe this is implicit) but I found this on [code project](http://www.codeproject.com/Articles/217176/Embedding-and-inlining-resources-in-ASP-NET-Web-Co) "The logical name is case sensitive, even though it contains file names which are generally not case sensitive" – Guish Feb 12 '15 at 15:43
  • Yeah the only error I saw that pointed me in the right direction was an Event Log error level message that said "An error occurred processing a web or script resource request...". I looked at that path SO many times before realizing the "J" in my jQuery project's folder path was lowercase, where the string I sent to the webresource had it uppercase. – Zack Feb 12 '15 at 16:25
1

this blog is two years old now... but I I spent days on trying to get this to work. Trying to get an embedded js file to actually give me a WebResource.asx query string that would work. The final piece that seems to get glossed over here is that the file you have embedded HAS to be in the same physical directory structure as the controls code-behind that you are calling GetWebResourceUrl() from. If you've placed the embedded file in a folder called "scripts", then called GetWebResourceUrl() from the master page which is NOT found in "scripts", the ResourceURL returned will point to the wrong location... thus ALWAYS returning a 404.

if you are using the MasterPage as the type for the first param then it will never work. GetWebResourceUrl(typeof(MasterPage),... I guess the real key here is that you have to drop the embedded resource into the same location that you are going to use as the type for the first parameter of the ResourceURL. After 3 days of wrestling with this thing, it finally found my Resource.

khr055
  • 28,690
  • 16
  • 36
  • 48
david
  • 11
  • 1
1

This is clutching at straws a bit, but could it be that your asp.net isn't set up to process the webresource.axd correctly? If something has gone wrong maybe the handler tag is missing from the machine's web.config?

The http handlers tag of C:\Windows\Microsoft.NET\Framework\v2.0.50727\CONFIG\web.config should have a webresource.axd entry like this:

<httpHandlers>
    <add path="WebResource.axd" verb="GET" type="System.Web.Handlers.AssemblyResourceLoader" validate="True"/>
</httpHandlers>

Also double check there isn't any handler entry in the project's web.config that could be overriding the setting from the machine's web.config.

Helephant
  • 16,738
  • 8
  • 39
  • 36
1

For anyone who happens to be using VB - there is a difference in behavior between the VB compiler and the C# compiler.

In VB the embedded resource HAS to be at the root level of your project. When I looked at the generated assembly with ILDASM I found that the name of the embedded resource NEVER includes the names of any subfolders. This eventually causes the AssemblyLoader to look in the wrong place for the embedded resource.

When you repeat the experiment with C# it DOES include the names of the subfolders.

EDIT - Changed to reflect that for VB the resource it HAS to be at the root level.

What I succeeded with was to have the embedded resource in the same folder as the code that uses it (nicer for source control). I then LIED in the Attribute AND the Page.ClientScript.GetWebResourceUrl call to account for the VB compiler claiming that the embedded resource has no paths.

RichardHowells
  • 7,826
  • 3
  • 24
  • 24
0

[assembly: ] attributes have to be in the Properties\AssemblyInfo.cs file. Even though the project is compiled when assembly attributes are in the custom control file, they are not visible to WebResource.axd.

kerem
  • 2,699
  • 1
  • 32
  • 37
0

The answer to your question completely depends on where you have this file in your actual project, and what the default namespace is. As Chris mentioned, the path you provide to the methods that register the script need the right path to locate the embedded resource. You don't just match the string you specify in your AssemblyInfo. The string has to be the correct path to the resource.

< default project namespace >/< any subfolders you have the file in >/< filename >

sliderhouserules
  • 3,415
  • 24
  • 32
0

Turn this one;

Page.ClientScript.RegisterClientScriptInclude("NavigationScript"...

into this;

Page.ClientScript.RegisterClientScriptInclude("CompanyProduct.Library.navigation.js"...
Thomas Hansen
  • 5,523
  • 1
  • 23
  • 28
0

I had a similar situation, and after about 4 hours of researching and testing I got the final solution: the Default Namespace must be the same as the Assembly Name.
(One could use Reflector or use the below code snippet to get the names of the embedded resources.

string[] embeddedResNames = Assembly.LoadFile("YourDll.dll").GetManifestResourceNames()
jaraics
  • 4,239
  • 3
  • 30
  • 35
0

Is the resource that you're adding in a different assembly to the code that you're using to generate the script tag? If that's the case, I think the this.GetType() will return a reference to a type in the wrong assembly so the web resource code won't have the right assembly to load the resource from.

I don't know for sure that this would be a problem but it seems to me that the code that generated the name would need to know what assembly the resource was on or it wouldn't be able to map back to that assembly when it received the request from the browser.

Helephant
  • 16,738
  • 8
  • 39
  • 36
0

After trying most of the solutions here, I came across this other StackOverflow answer which worked.

The time that is stamped on the DLL must be after the current time, otherwise WebResource.axd will not serve resources from it.

This mechanism seems to be completely unaware of time zone differences. If your CI server is in a time zone that is further east than your target web server, the time difference between the zones makes the resources unavailable until the web server time reaches the time on the DLL. The solution is to ensure your CI agent's time zone is set to the same as (or further west than) your target servers using Set-TimeZone in your build script.

Of course, the ideal solution is to set all servers to UTC, but not all applications are coded to be time zone independent.

NightOwl888
  • 55,572
  • 24
  • 139
  • 212
0

As meandmycode already mentioned, the type passed to GetWebResourceUrl is the key

I didn't fancy passing type where it does not really matter, I solved it with this kind of helper method

static public string GetEmbeddedResourceLink(Page page, string assemblyName, string resource) {
    var assembly = Assembly.Load(assemblyName);
    var types = assembly.GetTypes();
    if (types.Length == 0) {
        throw new ArgumentException("assembly does not contain any type");
    }
    return page.ClientScript.GetWebResourceUrl(types[0], resource);
}
Christian Specht
  • 35,843
  • 15
  • 128
  • 182
mizuki nakeshu
  • 1,315
  • 2
  • 9
  • 12