다음을 통해 공유


캐시된 페이지에 동적 콘텐츠 추가(VB)

작성자: Microsoft

동일한 페이지에서 동적 및 캐시된 콘텐츠를 혼합하는 방법을 알아봅니다. 캐시 후 대체를 사용하면 출력 캐시된 페이지 내에서 배너 광고 또는 뉴스 항목과 같은 동적 콘텐츠를 표시할 수 있습니다.

출력 캐싱을 활용하여 ASP.NET MVC 애플리케이션의 성능을 크게 향상시킬 수 있습니다. 페이지가 요청될 때마다 페이지를 다시 생성하는 대신 페이지를 한 번 생성하고 여러 사용자에 대한 메모리에 캐시할 수 있습니다.

그러나 문제가 있습니다. 페이지에 동적 콘텐츠를 표시해야 하는 경우 어떻게 해야 합니까? 예를 들어 페이지에 배너 광고를 표시하려는 경우를 생각해 보십시오. 모든 사용자가 동일한 광고를 볼 수 있도록 배너 광고를 캐시하지 않습니다. 당신은 그런 식으로 돈을 벌지 않을 것입니다!

다행히도 쉬운 솔루션이 있습니다. 캐시 후 대체라는 ASP.NET 프레임워크의 기능을 활용할 수 있습니다. 캐시 후 대체를 사용하면 메모리에 캐시된 페이지의 동적 콘텐츠를 대체할 수 있습니다.

일반적으로 OutputCache> 특성을 사용하여 <페이지를 캐시하는 경우 페이지는 서버와 클라이언트(웹 브라우저) 모두에 캐시됩니다. 캐시 후 대체를 사용하는 경우 페이지는 서버에만 캐시됩니다.

캐시 후 대체 사용

캐시 후 대체를 사용하려면 두 단계가 필요합니다. 먼저 캐시된 페이지에 표시할 동적 콘텐츠를 나타내는 문자열을 반환하는 메서드를 정의해야 합니다. 다음으로, HttpResponse.WriteSubstitution() 메서드를 호출하여 동적 콘텐츠를 페이지에 삽입합니다.

예를 들어 캐시된 페이지에 다른 뉴스 항목을 임의로 표시하려는 경우를 상상해 보십시오. 목록 1의 클래스는 3개의 뉴스 항목 목록에서 하나의 뉴스 항목을 임의로 반환하는 RenderNews()라는 단일 메서드를 노출합니다.

목록 1 – Models\News.vb

Public Class News

    Shared Function RenderNews(ByVal context As HttpContext) As String
        Dim newsItems As New List(Of String)
        newsItems.Add("Gas prices go up!")
        newsItems.Add("Life discovered on Mars!")
        newsItems.Add("Moon disappears!")

        Dim rnd As New Random()
        Return newsItems(rnd.Next(newsItems.Count))
    End Function

End Class

캐시 후 대체를 활용하려면 HttpResponse.WriteSubstitution() 메서드를 호출합니다. WriteSubstitution() 메서드는 캐시된 페이지의 영역을 동적 콘텐츠로 바꾸는 코드를 설정합니다. WriteSubstitution() 메서드는 목록 2의 보기에 임의의 뉴스 항목을 표시하는 데 사용됩니다.

목록 2 – Views\Home\Index.aspx

<%@ Page Language="VB" Inherits="System.Web.Mvc.ViewPage" %>
<%@ Import Namespace="MvcApplication1" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head id="Head1" runat="server">
    <title>Index</title>
</head>
<body>
    <div>
    
    <% Response.WriteSubstitution(AddressOf News.RenderNews)%>
        
    <hr />
    
    The content of this page is output cached.
    <%= DateTime.Now %>

    </div>
</body>
</html>

RenderNews 메서드는 WriteSubstitution() 메서드에 전달됩니다. RenderNews 메서드가 호출되지 않습니다. 대신 AddressOf 연산자의 도움을 받아 메서드에 대한 참조가 WriteSubstitution()에 전달됩니다.

인덱스 보기가 캐시됩니다. 보기는 목록 3의 컨트롤러에 의해 반환됩니다. Index() 작업은 Index 뷰가 60초 동안 캐시되도록 하는 OutputCache> 특성으로 데코레이<팅됩니다.

목록 3 – Controllers\HomeController.vb

<HandleError()> _
Public Class HomeController
    Inherits System.Web.Mvc.Controller

    <OutputCache(Duration:=60, VaryByParam:="none")> _
    Function Index()
        Return View()
    End Function

End Class

인덱스 보기가 캐시되더라도 인덱스 페이지를 요청할 때 다른 임의 뉴스 항목이 표시됩니다. 인덱스 페이지를 요청하면 페이지에 표시되는 시간이 60초 동안 변경되지 않습니다(그림 1 참조). 시간이 변경되지 않는다는 사실은 페이지가 캐시됨을 증명합니다. 그러나 WriteSubstitution() 메서드(임의 뉴스 항목)에 의해 삽입된 콘텐츠는 각 요청에 따라 변경됩니다.

그림 1 – 캐시된 페이지에 동적 뉴스 항목 삽입

clip_image002

도우미 메서드에서 캐시 후 대체 사용

캐시 후 대체를 활용하는 더 쉬운 방법은 사용자 지정 도우미 메서드 내에서 WriteSubstitution() 메서드에 대한 호출을 캡슐화하는 것입니다. 이 방법은 목록 4의 도우미 메서드에 의해 설명됩니다.

목록 4 – Helpers\AdHelper.vb

Imports System.Runtime.CompilerServices

Public Module AdHelper

    <Extension()> _
    Sub RenderBanner(ByVal helper As HtmlHelper)
        Dim context = helper.ViewContext.HttpContext
        context.Response.WriteSubstitution(AddressOf RenderBannerInternal)
    End Sub

    Private Function RenderBannerInternal(ByVal context As HttpContext) As String
        Dim ads As New List(Of String)
        ads.Add("/ads/banner1.gif")
        ads.Add("/ads/banner2.gif")
        ads.Add("/ads/banner3.gif")

        Dim rnd As New Random()
        Dim ad = ads(rnd.Next(ads.Count))
        Return String.Format("<img src='{0}' />", ad)
    End Function

End Module

목록 4에는 RenderBanner() 및 RenderBannerInternal()의 두 가지 메서드를 노출하는 Visual Basic 모듈이 포함되어 있습니다. RenderBanner() 메서드는 실제 도우미 메서드를 나타냅니다. 이 메서드는 다른 도우미 메서드와 마찬가지로 보기에서 Html.RenderBanner()를 호출할 수 있도록 표준 ASP.NET MVC HtmlHelper 클래스를 확장합니다.

RenderBanner() 메서드는 WriteSubstitution() 메서드에 RenderBannerInternal() 메서드를 전달하는 HttpResponse.WriteSubstitution() 메서드를 호출합니다.

RenderBannerInternal() 메서드는 프라이빗 메서드입니다. 이 메서드는 도우미 메서드로 노출되지 않습니다. RenderBannerInternal() 메서드는 세 개의 배너 광고 이미지 목록에서 하나의 배너 광고 이미지를 임의로 반환합니다.

목록 5의 수정된 인덱스 보기는 RenderBanner() 도우미 메서드를 사용하는 방법을 보여 줍니다. <보기 맨 위에 추가 %@ Import %> 지시문이 포함되어 MvcApplication1.Helpers 네임스페이스를 가져옵니다. 이 네임스페이스를 가져오지 않으면 RenderBanner() 메서드가 Html 속성에 메서드로 표시되지 않습니다.

목록 5 – Views\Home\Index.aspx(RenderBanner() 메서드 사용)

<%@ Page Language="VB" Inherits="System.Web.Mvc.ViewPage" %>
<%@ Import Namespace="MvcApplication1" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head id="Head1" runat="server">
    <title>Index</title>
</head>
<body>
    <div>
    
    <% Response.WriteSubstitution(AddressOf News.RenderNews)%>
    
    <hr />
    
    <% Html.RenderBanner()%>
    
    <hr />
    
    The content of this page is output cached.
    <%= DateTime.Now %>
    
    </div>
</body>
</html>

목록 5의 보기에서 렌더링된 페이지를 요청하면 각 요청과 함께 다른 배너 광고가 표시됩니다(그림 2 참조). 페이지는 캐시되지만 배너 보급 알림은 RenderBanner() 도우미 메서드에 의해 동적으로 삽입됩니다.

그림 2 - 임의 배너 광고를 표시하는 인덱스 보기

clip_image004

요약

이 자습서에서는 캐시된 페이지에서 콘텐츠를 동적으로 업데이트하는 방법을 설명했습니다. HttpResponse.WriteSubstitution() 메서드를 사용하여 동적 콘텐츠를 캐시된 페이지에 삽입하는 방법을 알아보았습니다. HTML 도우미 메서드 내에서 WriteSubstitution() 메서드 호출을 캡슐화하는 방법도 알아보았습니다.

가능하면 캐싱을 활용합니다. 이는 웹 애플리케이션의 성능에 큰 영향을 미칠 수 있습니다. 이 자습서에서 설명한 대로 페이지에 동적 콘텐츠를 표시해야 하는 경우에도 캐싱을 활용할 수 있습니다.