2010-12-12 4 views
3

내 HTML의 일부 텍스트를 바꾸기 위해 ActionFilter을 만들려고합니다. 기본적으로 서버가 SSL을 사용하고있을 때 내 CDN (http://cdn.example.com)에 대한 참조를 내 서버 (https://www.example.com)에 대한 참조로 직접 대체하려고합니다. 이 내 보안 컨트롤러에 사용되는ASP.NET MVC ActionFilter를 사용하여 렌더링 된 HTML의 URL을 대체하는 방법

public class CdnSslAttribute : ActionFilterAttribute 
{ 
    public override void OnResultExecuted(ResultExecutedContext filterContext) 
    { 
     if(filterContext.HttpContext.Request.IsSecureConnection) 
     { 
      // when the connection is secure, 
      // somehow replace all instances of http://cdn.example.com 
      // with https://www.example.com 
     } 
    } 
} 

:

[CdnSsl] 
public class SecureController : Controller 
{ 
} 

내가 이렇게 할 이유 그래서 구조는 다음과 같은 것을 (나는 내가 시작해야하는 위치가 OnResultExecuted 가정)입니다 내 CDN이 SSL을 지원하지 않습니다. 마스터 페이지에는 CDN 리소스에 대한 참조가 있습니다. 예 :

<link href="http://cdn.example.com/Content/base.css" rel="stylesheet" type="text/css" /> 

답변

5

나는이 블로그 게시물의 변형 사용하여 종료 : 내 자신의 필터를

http://arranmaclean.wordpress.com/2010/08/10/minify-html-with-net-mvc-actionfilter/

을 :

public class CdnSslAttribute : ActionFilterAttribute 
{ 
    public override void OnResultExecuted(ResultExecutedContext filterContext) 
    { 
     if (filterContext.HttpContext.Request.IsSecureConnection) 
     { 
      var response = filterContext.HttpContext.Response; 
      response.Filter = new CdnSslFilter(response.Filter); 
     } 
    } 
} 

그런 다음 필터 (일부 코드가 간결하게 생략) 다음과 같습니다 :

public class CdnSslFilter : Stream 
{ 
    private Stream _shrink; 
    private Func<string, string> _filter; 

    public CdnSslFilter(Stream shrink) 
    { 
     _shrink = shrink; 
     _filter = s => Regex.Replace(s,@"http://cdn\.","https://www.", RegexOptions.IgnoreCase); 
    } 

    //overridden functions omitted for clarity. See above blog post. 

    public override void Write(byte[] buffer, int offset, int count) 
    { 
     // capture the data and convert to string 
     byte[] data = new byte[count]; 
     Buffer.BlockCopy(buffer, offset, data, 0, count); 
     string s = Encoding.Default.GetString(buffer); 

     // filter the string 
     s = _filter(s); 

     // write the data to stream 
     byte[] outdata = Encoding.Default.GetBytes(s); 
     _shrink.Write(outdata, 0, outdata.GetLength(0)); 
    } 
} 
0

나도 몰라하지만 question에서 @Haacked의 답변이 도움이 될 수.

0

액션 필터 내부에서 생성 된 출력에 대한 대체 작업은 약간 복잡 할 수 있습니다.

쉬운 방법 (마스터 페이지를 편집 할 수있는 경우)은 조건부로 올바른 URL을 내보내는 새로운 Html 도우미 메서드 (Html.Content() 도우미와 유사 함)를 작성하는 것이 좋습니다. 그 교체가 특정 컨트롤러에서만 일어나기를 바란다면 액션 필터를 여전히 가질 수는 있지만 Request.Items에 플래그를 설정하면 도우미가 해당 플래그를 확인할 수 있습니다.

0

@ marcind의 접근법을 따르는 것이 좋습니다. 한 가지 방법은 맞춤 URL 확장 방법을 사용하여 현재 URL 스키마에 따라 올바른 URL을 생성하는 것입니다. 이 확장 메서드에 대한 호출과이 방법의

public static MvcHtmlString CdnActionLink(this HtmlHelper helper, string linkText, string actionName, string controllerName) 
{ 
    if(helper.ViewContext.HttpContext.Request.IsSecureConnection) 
    { 
     return helper.ActionLink(linkText, actionName, controllerName, "https", "www.yourhost.com"...); 
    } 
    return helper.ActionLink(linkText, actionName, controllerName); 
} 

한 가지 단점은 당신이보기에 현재 모든 ActionLink 호출을 교체해야한다는 것입니다 (또는 적어도 사람은 당신이 필요합니다).

+0

개발자가 소스 코드로 작업하고 있는지 여부는 모두 다릅니다. "소유하지"마십시오. 코드를 수정할 수없는 시스템 용 플러그인을 개발 중입니다. 즉, UI의 특정 부분을 변경하기 위해 응답을 수정해야 함을 의미합니다. –

관련 문제