Não é possível acessar o recurso incorporado no asp.net

Estou tentando mover uma imagem e uma folha de estilos de um controle de usuário para resources incorporados na assembly. Eu usei o Reflector para ver que a imagem e o arquivo .css estão incorporados na assembly, mas quando tento acessá-los usando a URL criada pelo ClientScript.GetWebResourceUrl (), o recurso não é encontrado. Estou perplexo.

Namespace padrão de assembly:

TestWebApp 

Os caminhos para os arquivos (marcados como BuildAction: Embedded Resource) são

 TestWebApp/Resources/CSS/PaymentHistory.css TestWebApp/Resources/Images/loading.gif 

E assim meus resources são registrados como:

 [assembly: WebResource("TestWebApp.Resources.CSS.PaymentHistory.css", "text/css", PerformSubstitution = true)] [assembly: WebResource("TestWebApp.Resources.Images.loading.gif", "image/gif")] 

Controle de usuário (na mesma assembly) que acessa os resources:

 TestWebApp.UserControls.PaymentHistory 

Para simplificar, atualmente estou tentando apenas referenciar a imagem e não a folha de estilo. No Page_Load do meu controle de usuário, eu defino o ImageUrl de um controle de imagem para o URL do recurso:

 image1.ImageUrl = Page.ClientScript.GetWebResourceUrl(this.GetType(), "TestWebApp.Resources.Images.loading.gif"); 

Em tempo de execução, tudo parece funcionar sem erros, mas renderiza uma imagem quebrada. Aqui está a fonte da imagem renderizada:

  

Se eu navegar para esse URL no meu navegador, recebo um 404, o recurso não pode ser encontrado. O que estou fazendo de errado?

EDIT: Deve haver algo fundamental que eu não estou entendendo e / ou estou fazendo algo realmente estúpido. Aqui está um exemplo simples do VS 2010 . Eu segui todas as etapas necessárias para incorporar o JScript1.js e acessá-lo via WebResource.axd, mas ele recebe o erro.

No arquivo Default.aspx.cs do seu projeto de exemplo, altere this.GetType() para typeof(_Default) :

 Page.ClientScript.RegisterClientScriptInclude("JScript1", Page.ClientScript.GetWebResourceUrl(typeof(_Default), "EmbeddedResources.JScript1.js")); 

Da mesma forma, no arquivo PaymentHistory.ascx.cs, altere this.GetType() para typeof(PaymentHistory) :

 image1.ImageUrl = Page.ClientScript.GetWebResourceUrl( typeof(PaymentHistory), "TestWebApp.Resources.Images.loading.gif"); 

Explicação: GetWebResourceUrl examina o argumento de type para determinar qual assembly contém o recurso incorporado. Especificando this.GetType() como o type está incorreto porque, em uma class code-behind .aspx ou .ascx, this.GetType() não se refere a essa class, mas sim à class derivada que é gerada dinamicamente a partir do .aspx ou Marcação .ascx. Essa class derivada reside em um assembly separado, portanto GetWebResourceUrl não pode localizar o recurso incorporado.

O recurso está em um projeto separado ou no mesmo projeto que seu controle de usuário? Se separado, você terá que replace this.GetType () pela function GetType () de um object que reside no projeto separado.

Se no mesmo projeto, basta fazer Page.GetType (), porque você quer uma referência para a página e não o controle do usuário

Primeiro de tudo, o tipo que você está passando para a chamada GetWebResourceUrl (ou para o RegisterClientScriptResource eu mostro abaixo) está realmente lá para apontar para qual assembly contém seu recurso. O problema é que “this.GetType ()” está retornando um tipo que não está no assembly em execução atual (por mais estranho que isso possa ser).

As duas linhas seguintes demonstram o problema.

  Response.Write(this.GetType().Assembly.FullName + "
"); Response.Write(Assembly.GetExecutingAssembly().FullName + "
");

A primeira linha retorna o nome de um “App_Web _ ??????” assembly. O segundo retorna o conjunto “EmbeddedResources” esperado.

Na chamada abaixo, eu apenas passo o primeiro tipo que recebo do assembly em execução e a chamada funciona. Page.ClientScript.RegisterClientScriptResource (Assembly.GetExecutingAssembly (). GetTypes () [0], nomes [0]);

this.GetType () na verdade retorna um tipo que o servidor da web cria que herda do seu tipo. É por isso que typeof (_Default) também funcionaria para designar a assembly correta.

Aqui você pode ver um código em Vb.NET que usa a biblioteca de reflection para detectar o nome do assembly atual e o atual NameSpace.

Se você concatenar o namespace com o nome da imagem incorporada, você pode usar o comando Page.clientScript.GetWebResourceURL para gerar um link para a imagem como você vê na primeira function

Na segunda function, você vê um loop em todo o nome dos resources até encontrar o nome completo do recurso incorporado.

 Friend Class ReadResources ' Get our assembly. Private Shared executingAssembly As System.Reflection.Assembly = Reflection.Assembly.GetExecutingAssembly() ' Get our namespace. Private Shared myNamespace As String = executingAssembly.GetName().Name.ToString() '''  ''' Generate resource link '''  Friend Shared Function GetResourceLink(ByVal ref As String, ByVal obj As Object, ByVal page As Web.UI.Page) As String Dim out As String = Nothing out = Page.ClientScript.GetWebResourceUrl(obj.GetType, myNamespace & "." & ref) If out Is Nothing OrElse out.Length <= 0 Then out = FindResource(ref, obj) End If Return out End Function Friend Shared Function FindResource(ByVal reference As String, ByVal obj As Object) As String Dim out As String = "" For Each embedded In obj.GetType().Assembly.GetManifestResourceNames() If embedded.Contains(reference) Then out = embedded Exit For End If Next Return out End Function End Class