2013-08-29 5 views
6

이미지 및 스타일 시트를 사용자 정의 컨트롤에서 어셈블리의 포함 된 리소스로 이동하려고합니다. Reflector를 사용하여 이미지와 .css 파일이 어셈블리에 포함되어 있는지 확인했지만 ClientScript.GetWebResourceUrl()로 만든 URL을 사용하여 리소스에 액세스하려고하면 리소스를 찾을 수 없습니다. 나는 혼란 스럽다.asp.net의 포함 된 리소스에 액세스 할 수 없습니다.

조립 기본 네임 스페이스 :

TestWebApp 

파일에 대한 경로 (BuildAction으로 표시 : 포함 리소스)입니다을

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

그래서 내 자원은 다음과 같이 등록 :

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

리소스에 액세스하는 사용자 컨트롤 (동일한 어셈블리에서) :

TestWebApp.UserControls.PaymentHistory 

간단히 말해서, 저는 현재 이미지 만 참조하고 스타일 시트는 참조하지 않고 있습니다. 내 사용자 컨트롤의를 Page_Load에서 나는 자원 URL에 이미지 컨트롤의 이미지 URL 설정 :

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

런타임시, 모든 오류없이 작동하도록 나타납니다하지만 깨진 이미지를 렌더링합니다. 다음은 렌더링 된 이미지 소스 :

내 브라우저에서 해당 URL로 이동하는 경우
<img style="border-width:0px;" src="/WebResource.axd?d=8fC_1tLPjrUCxmFc_Q2MKY0-pHAak-sTWkpLLV3D56H_c08LujXC63ia2PNICE65_i-Q4JqprAigLpbrXG-rIAr6ePO4HHcdQKgdd3szlThv2gizxOJLJsPRNe-b_M6ApTwPsH_5oZAuONTN0cumOTRr1nA1&amp;t=635133745137507721" id="ph1_image1"> 

, 나는 404 얻을, 리소스를 찾을 수 없습니다. 내가 도대체 ​​뭘 잘못하고있는 겁니까?

편집 : 근본적인 것이 틀림 없습니다. 나는 이해하지 못하고 있고, 나는 정말 바보 같은 짓을하고 있습니다. Here is a simple VS 2010 example. JScript1.js를 포함하고 WebResource.axd를 통해 액세스하는 데 필요한 모든 필요한 단계를 수행했지만 오류가 발생합니다.

+2

디버그에서 Assembly.GetExecutingAssembly(). GetManifestResourceNames();를 확인하십시오. 예상하는 자원 이름을 리턴합니다. 또한 문자열 상수를 사용하여 WebResource 특성과 GetWebResourceUrl 명령에서 동일한 문자열을 사용하고 있는지 확인하십시오. – Grax

+0

@Grax - 감사합니다. GetManifestResourceNames()를 사용하여 여러 가지 방법으로 사용중인 문자열이 모두 정확히 일치하고 올바른지 확인했습니다. 또한 하위 폴더에서 리소스를 프로젝트 루트로 옮겨 보았습니다. 나는 내가 지금 "image/gif"로 바꾼 잘못된 콘텐츠 유형 "img/gif"를 발견했으나 놀랍게도 그것을 고치지 않았습니다. 나는 또한 출력 윈도우가 "This is invalid webresource request."라는 두 개의 System.Web.HttpExceptions를 로깅하고 있음을 확인했습니다. 나는 그것이 왜 2 가지인지 모르겠다. 나의 추측은 firefox이거나 "Cassini"가 자동적으로 재 시도했다. – xr280xr

+0

@Grax 만약 당신이 그것을 시험해보고 싶다면 예제로 질문을 업데이트했습니다. – xr280xr

답변

9

를 원하기 때문에 같은 프로젝트에서, 단지 Page.GetType()를 할 경우, this.GetType() 변경 typeof(_Default)에 : 마찬가지로

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

의 PaymentHistory.ascx.cs 파일에 변경 this.GetType()typeof(PaymentHistory)에 :

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

설명 :GetWebResourceUrltype 인수를보고 포함 된 리소스가 포함 된 어셈블리를 확인합니다. .aspx 또는 .ascx 코드 숨김 클래스에서 this.GetType()이 아닌이 해당 클래스를 나타내며 .aspx 또는 .ascx 태그에서 동적으로 생성되는 파생 클래스를 나타내므로 type으로 지정하면 이 올바르지 않습니다.이 파생 클래스는 별도의 어셈블리에 있으므로 GetWebResourceUrl 포함 된 리소스를 찾을 수 없습니다.

+0

와우,이 문제를 확인하지 못했다고 생각합니다 .GetType()을 사용하여 문제를 해결하십시오. 그러나 미리 컴파일 된 페이지 및 컨트롤에 대해 클래스가 생성 된 것을 전혀 알지 못했습니다. 고마워요, 마이클! – xr280xr

+0

@ xr280xr : 천만에. :-) –

1

리소스가 별도의 프로젝트에 있거나 사용자 정의 컨트롤과 동일한 프로젝트에 있습니까? 별도의 경우 this.GetType()을 별도의 프로젝트에있는 개체의 GetType() 함수로 대체해야합니다.

당신이 페이지에 대한 참조와 예제 프로젝트의하여 default.aspx.cs 파일에없는 사용자 제어

+0

귀하의 질문에 대한 답변은 제 OP에서 받았지만 세부 사항을 지적 해 주셔서 감사합니다. Page.GetType()을 사용해도 문제가 해결되지 않습니다.필요한 모든 메서드는 리소스를 포함하는 어셈블리의 형식입니다. 내 경우에는 페이지와 사용자 정의 컨트롤 모두 해당 기준을 충족하므로 차이가 없어야합니다. – xr280xr

1

우선 GetWebResourceUrl 호출 (또는 아래에 나와있는 RegisterClientScriptResource)에 전달하는 형식은 실제로 어떤 어셈블리에 리소스가 들어 있는지 가리키는 곳입니다. 문제는 "this.GetType()"이 현재 실행중인 어셈블리에없는 형식을 반환하고 있다는 것입니다.

다음 두 줄이 문제를 설명합니다.

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

첫 번째 줄에는 "App_Web _ ??????" 어셈블리. 두 번째는 예상 된 "EmbeddedResources"어셈블리를 반환합니다.

아래의 호출에서 나는 실행중인 어셈블리에서 돌아오고 호출이 작동하는 첫 번째 유형을 전달합니다. Page.ClientScript.RegisterClientScriptResource (Assembly.GetExecutingAssembly(). GetTypes() [0], names [0]);

this.GetType()은 웹 서버가 사용자 유형에서 상속하는 유형을 실제로 반환합니다. 이것이 typeof (_Default)가 올바른 어셈블리를 지정하는 이유이기도합니다.

+0

'GetTypes() [0]'을 사용하면 필요하지만 필요할 때 어셈블리의 모든 유형을로드하는 것이 약간 비효율적 인 것처럼 보입니다. –

0

Reflection 라이브러리를 사용하여 현재 어셈블리 이름과 현재 NameSpace를 검색하는 코드를 Vb.NET에서 볼 수 있습니다. 당신이 포함 된 이미지의 이름으로 네임 스페이스를 연결할 경우

, 당신은 당신이 두 번째 함수에서 첫 번째 함수

에서 보는 바와 같이 이미지에 대한 링크를 생성하는 명령 Page.clientScript.GetWebResourceURL을 사용할 수 있습니다, 당신은 모두 루프를 참조 임베디드 리소스의 전체 이름을 찾을 때까지 리소스 이름을 지정합니다.

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() 

    ''' <summary> 
    ''' Generate resource link 
    ''' </summary> 
    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 
+0

코드 전용 답변을 피하십시오. 추천에 따라 코드 – MickyD

+0

에 설명을 추가하는 것을 고려해보십시오. –