2010-03-27 5 views
2

웹 응용 프로그램의 모든 이미지를 CDN으로 이동하는 과정에 있지만 경로를 하드 코딩하지 않고도 CDN을 쉽게 켜거나 끌 수 있습니다. 이미지.ASP.NET의 이미지 용 CDN

내 첫 번째 생각은 web.config의 변수가 서버 또는 CDN의 이미지를 제공하는지 여부에 따라 이미지 확장을위한 HttpHandler를 추가하는 것이 었습니다. 그러나 이것이 약간을 제공 한 후에는 ASP.NET이 모든 단일 이미지에 대한 요청을 처리하여 오버 헤드가 추가되고 실제로 CDN 사용의 이점을 완전히 줄일 수 있기 때문에 본질적으로이를 배제했다고 생각합니다.

내 페이지가 모두 기본 페이지 클래스에서 상속되기 때문에 기본 클래스에서 web.config 변수를 기반으로 파일을 제공 할 경로를 결정하는 함수를 만들 수 있습니다. 나는 다음 마크 업에 이런 짓을 할 것이다 :

<img src='<%= GetImagePath()/image.png' /> 

나는 이것이 내가이 일을 끝낼해야합니다 아마 무슨 생각하지만 그것은 나에게 조금 어설픈 것 같다. 나는 또한 "< %"솔루션이 작동하지만 "< % ="때문에 컨트롤 컬렉션을 수정할 수 없다는 기존의 .NET 오류에 대해 생각하고 있습니다.

구현 방법에 대한 의견이나 제안이 있으십니까? 당신이 루프 모든 컨트롤을 할 수 귀하의 기본 클래스의 PreRender 이벤트의 이미지 URL을 변경

답변

2

당신은 미리 최적화의 가정을 기반으로 HttpHandler 작성 기각했습니다. 나는 이것을 재검토하고 간단히 HttpHandler이라고 쓰고 그것을 시험해 보겠다. Page 메서드 솔루션이 느려질 수도 있습니다. 특히 ASP 전처리 기가 관련된 경우 더욱 그렇습니다.

HttpHandlers는 금속에 매우 가깝습니다. IIS가 ASP.Net에 요청을 전달하는 데 드는 오버 헤드가 아주 작습니다. 그것은 당신이 제안하는 것보다 더 우아한 해결책이 될 것이며, 아마도 더 확장 성이 있고 나는 기꺼이 내기를 할 것입니다.

+0

에 기사를 썼다. . . 내 생각에 꽤 사려 깊지. 가장 큰 걱정은 각 이미지 요청이 CDN에서 이미지를 요청하고 CDN의 응답 헤더에서 수행 된 클라이언트 쪽 캐싱을 완화 할 수 있다는 것입니다. 그 결정을 내리기 위해 두포에서 진행되는 일에 대해 충분히 알지 못합니다. – Chris

+0

HttpHandler가 이미지 데이터를 서버하면 CDN을 사용하여 대역폭을 절약 할 수 없습니다. 또 다른 옵션은 HttpHandler가 동일한 URL의 CDN 버전에 302를 보내도록하는 것입니다. – David

0

HTTP 처리기 접근법에 대한 좋은 점은 위치를 기반으로 처리 할 img 경로를 식별 할 수 있다는 점입니다. HTTPS 처리기가 도움이된다고 가정하면 처리 할 수 ​​있습니다.

가능한 단점은 이미지 파일 확장명 (.jpg, .png 등)이 asp.net 파이프 라인에 자동으로 전달되지 않는다는 것입니다. 당신은 쉽게 그렇게하도록 IIS를 설정할 수 있습니다 -하지만 당신은 IIS 이상의 contriol의 특정 수준을해야합니다 - 그래서 당신이 공유 호스팅 환경에 있다면 옵션이되지 않을 수도 있습니다.

2

좀 더 간단한 방법을 고려해 보셨습니까?

페이지가 모두 기본 클래스에서 상속 된 경우 앞에 URL이 포함 된 페이지의 속성을 CDN (또는 CDN을 끄려면 로컬 서버)에 노출시킬 수 있습니다. 웹에 prepend URL을 저장하는 것은 사소한 일입니다.설정 : 당신의 <appSettings/> 요소에서

public string PrependURLPath() { 
get { return ConfigurationManager.AppSettings["ImagePrependURL"].ToString(); } 
} 

, 당신은 단순히 예를 들어, 앞에 추가 URL이 어떻게 될지 선택할 수 있습니다

http://my.cdn.com/user/

또는 :

http://my.own.server.com/images/ 

매우 간단!

당신은 다음 예에 따라 이미지 refernces를 코딩 할 수있을 것입니다,하지만 기본 페이지 속성을 호출하면 원하는 경로 노출 :

<img src='<%= this.BasePage.PrependURLPath() + [YourImagePath.png] %>'/> 

내가 인라인 호출을 통해 이미지 소스를 설정하는 것에 동의를 지저분하지만 다른 사람들이 제안한대로 아마 당신의 페이지에있는 이미지 컨트롤을 반복하면서 앞 페이지 URL을 바꿔 가며 할 수 있습니다.

이 페이지는 현재 System.Web.UI.Page에서 상속하더라도, 그것은 System.Web.Page을 상속 자신의 기본 클래스를 제작하는 간단한 문제입니다, 다음 발견은/나머지에 솔루션으로 교체하는 페이지.

희망이 도움이됩니다.

using System.Web.UI.WebControls.Adapters; 
using System.Web.UI; 
using System.Web.UI.WebControls; 

namespace ExampleCode 
{ 
    public class ImageAdapter : WebControlAdapter 
    { 
     private bool UseCdn 
     { 
      get { return true; } // Get value from config or anywhere else 
     } 

     protected override void OnPreRender(EventArgs e) 
     { 
      base.OnPreRender(e); 

      Image image = (Image)Control; 

      if (UseCdn) 
      { 
       // If using relative urls for images may need to handle ~ 
       image.ImageUrl = String.Format("{0}/{1}", "CDN URL", image.ImageUrl); 
      } 
     } 
     } 
} 

다음 추가 : 당신이 당신의 이미지가 당신이 컨트롤 어댑터를 만들 수 태그를 사용하여 표시하는 경우

1

, 이들은이 트릭을 할해야 당신처럼 .NET 컨트롤이 렌더링 방식을 변경하거나 보편적으로 그들에게 뭔가를 변경할 수 있습니다 웹 프로젝트의 App_Browsers 폴더에있는 브라우저 파일은 다음과 같습니다.

<browsers> 
    <browser refID="Default"> 
     <controlAdapters> 
     <adapter 
      controlType="System.Web.UI.WebControls.Image" 
      adapterType="ExampleCode.ImageAdapter" 
      /> 
     </controlAdapters> 
    </browser> 
</browsers> 
0

이미지 관리를 위해 @Rhys 접근 방식을 선택합니다.

대부분의 경우 이미지 컨트롤을 사용하는 것보다 배경 이미지 CSS를 사용하려고합니다.

는 그 후 나는 상대 경로의 구름과 작업 벌금 함께 CSS와 이미지를 모두 업로드 할 수 있습니다.

2

꽤 늦게 계단을 올렸지 만 비슷한 솔루션을 직접 찾고있었습니다. 내가 뭘했는지 확인하는 Google 검색. HttpHandler 접근 방식을 고려하지 않은, 내가 단순히 ASP.net Image 컨트롤을 확장했다했다 :

public class Img : Image 
{ 
    public Img() 
    { 
     RelativePath = false; 
    } 

    public bool RelativePath { get; set; } 

    public override string ImageUrl 
    { 
     get 
     { 
      if (RelativePath) 
       return base.ImageUrl; 

      return "http://some.configurable-value.com" + base.ImageUrl; 
     } 
     set { base.ImageUrl = value; } 
    } 
} 

는 거칠고 준비하지만, 그것을 작동합니다 :) 분명히 문자열이 아닌 일부 설정 값에 의존해야 문자는하지만이 아직 그래서 여기 허용 대답하고 내 제안이다 것처럼 보이지 않는 큰 변화

0

아니다. URL을 투명하게 수정하는 것과 비슷한 문제가 있었지만 (다른 목적으로는 CDN 지원을 위해 사용하려고 생각했습니다).

이 오래된 필터/모듈이지만 조금 조정 내 요구에 잘 작동 : http://www.paraesthesia.com/archive/2007/12/14/urlabsolutifiermodule---convert-urls-in-asp.net-output-to-absolute.aspx

당신이 할 수있는 것은 응답 필터를 확인하고 HttpModule을 (이 absolutifier가하는대로)와 후크입니다.이 모듈 + 응답 필터를 사용하는 경우 CDN을 사용하기 위해 호스트 이름/접두사를 모두 바꾸려면 소스를 수정하여 필요한 것을 얻을 수 있습니다.

0

문제를 해결해야했는데, 개발 과정에서 CDN의 리소스를 사용하지 않고 웹 서버를 프로덕션 서버에 배포 할 때만 리소스를 사용하고 싶습니다. 이 문제를 해결하기 위해 프로덕션에서만 CDN URL을 앞에 추가하는 ExpressionBuilder를 개발했습니다.

<asp:Image ImageUrl="<%$ CdnUrl:/images/myimage.png %>" runat="server" /> 

이전 코드에서 CDN URL은 프로덕션에서만 추가됩니다. 자세한 내용은

namespace IdeaR.Web.Compilation 
{ 
[ExpressionPrefix("CdnUrl")] 
public class CdnUrlExpressionBuilder : ExpressionBuilder 
{ 
    public static object GetCdnUrl(string expression, Type target, string entry) 
    { 
     var retvalue = expression; 
     var productionUri = new Uri("http://www.myproductionurl.com", 
      UriKind.Absolute); 
     var currentUri = HttpContext.Current.Request.Url; 
     var cdnUrl = "http://cdn.mycdn.com"; 

     // If this is a production website URL 
     if (currentUri.Scheme == productionUri.Scheme && 
      currentUri.Host == productionUri.Host) 
      retvalue = cdnUrl + expression; 

     return retvalue; 
    } 

    public override CodeExpression GetCodeExpression(BoundPropertyEntry entry, 
     object parsedData, ExpressionBuilderContext context) 
    { 
     var componentType = entry.DeclaringType; 
     var expressionArray = new CodeExpression[3] 
     { 
      new CodePrimitiveExpression(entry.Expression.Trim()), 
      new CodeTypeOfExpression(componentType), 
      new CodePrimitiveExpression(entry.Name) 
     }; 

     var descriptor = TypeDescriptor.GetProperties(componentType) 
      [entry.PropertyInfo.Name]; 
     return new CodeCastExpression(descriptor.PropertyType, 
      new CodeMethodInvokeExpression(
       new CodeTypeReferenceExpression(GetType()), 
       "GetCdnUrl", expressionArray)); 
    }  
} 
} 

나는 내가 심지어 두 번째 방법은 관련된 ASP.net 프로세스를 얻을 수 몰랐어요 왜 그래, 난 잘 모르겠어요이 How to use a CDN in production but not during development