Reputation: 7430
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"));
Upvotes: 14
Views: 12681
Reputation: 56859
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.
Upvotes: 0
Reputation: 5160
I had a similar problem and, in my case, it was caused by the fact that Page.ClientScript.GetWebResourceUrl
resourceName parameter is case sensitive.
Upvotes: 1
Reputation: 416
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.
Upvotes: 1
Reputation: 2710
[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.
Upvotes: 0
Reputation: 11
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.
Upvotes: 1
Reputation: 9066
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.
Upvotes: 1
Reputation: 1354
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);
}
Upvotes: 0
Reputation: 4299
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()
Upvotes: 0
Reputation: 17317
Instead of this.GetType()
, get a type from the assembly that contains the resource.. ie:
typeof(Company.Product.Web.Library.Class1)
Does that work?
Upvotes: 14
Reputation: 1511
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.
Upvotes: 4
Reputation: 17028
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.
Upvotes: 0
Reputation: 17028
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.
Upvotes: 1
Reputation: 5513
Turn this one;
Page.ClientScript.RegisterClientScriptInclude("NavigationScript"...
into this;
Page.ClientScript.RegisterClientScriptInclude("CompanyProduct.Library.navigation.js"...
Upvotes: 0
Reputation: 3413
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 >
Upvotes: 0
Reputation: 32575
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()).
Upvotes: 3