Adicionar conteúdo dinâmico a uma página em cache (VB)
pela Microsoft
Saiba como misturar conteúdo dinâmico e armazenado em cache na mesma página. A substituição pós-cache permite exibir conteúdo dinâmico, como anúncios de faixa ou itens de notícias, em uma página que foi armazenada em cache.
Aproveitando o cache de saída, você pode melhorar drasticamente o desempenho de um aplicativo MVC ASP.NET. Em vez de regenerar uma página cada vez que a página é solicitada, a página pode ser gerada uma vez e armazenada em cache na memória para vários usuários.
Mas há um problema. E se você precisar exibir conteúdo dinâmico na página? Por exemplo, imagine que você deseja exibir um anúncio de faixa na página. Você não quer que o anúncio de faixa seja armazenado em cache para que todos os usuários vejam o mesmo anúncio. Você não ganharia dinheiro assim!
Felizmente, há uma solução fácil. Você pode aproveitar um recurso da estrutura de ASP.NET chamada substituição pós-cache. A substituição pós-cache permite substituir o conteúdo dinâmico em uma página que foi armazenada em cache na memória.
Normalmente, quando você gera um cache de uma página usando o <atributo OutputCache> , a página é armazenada em cache no servidor e no cliente (o navegador da Web). Quando você usa a substituição pós-cache, uma página é armazenada em cache somente no servidor.
Usando substituição pós-cache
O uso da substituição pós-cache requer duas etapas. Primeiro, você precisa definir um método que retorna uma cadeia de caracteres que representa o conteúdo dinâmico que você deseja exibir na página armazenada em cache. Em seguida, você chama o método HttpResponse.WriteSubstitution() para injetar o conteúdo dinâmico na página.
Imagine, por exemplo, que você deseja exibir aleatoriamente diferentes itens de notícias em uma página armazenada em cache. A classe na Listagem 1 expõe um único método, chamado RenderNews(), que retorna aleatoriamente um item de notícias de uma lista de três itens de notícias.
Listagem 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
Para aproveitar a substituição pós-cache, chame o método HttpResponse.WriteSubstitution(). O método WriteSubstitution() configura o código para substituir uma região da página armazenada em cache pelo conteúdo dinâmico. O método WriteSubstitution() é usado para exibir o item de notícias aleatório na exibição na Listagem 2.
Listagem 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>
O método RenderNews é passado para o método WriteSubstitution(). Observe que o método RenderNews não é chamado. Em vez disso, uma referência ao método é passada para WriteSubstitution() com a ajuda do operador AddressOf.
A exibição Índice é armazenada em cache. A exibição é retornada pelo controlador na Listagem 3. Observe que a ação Index() é decorada com um <atributo OutputCache> que faz com que a exibição Índice seja armazenada em cache por 60 segundos.
Listagem 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
Embora a exibição Índice seja armazenada em cache, diferentes itens de notícias aleatórias são exibidos quando você solicita a página Índice. Quando você solicita a página Índice, o tempo exibido pela página não é alterado por 60 segundos (consulte a Figura 1). O fato de que a hora não é alterada prova que a página está armazenada em cache. No entanto, o conteúdo injetado pelo método WriteSubstitution() – o item de notícias aleatório – é alterado com cada solicitação .
Figura 1 – Injetar itens de notícias dinâmicas em uma página armazenada em cache
Usando substituição pós-cache em métodos auxiliares
Uma maneira mais fácil de aproveitar a substituição pós-cache é encapsular a chamada para o método WriteSubstitution() dentro de um método auxiliar personalizado. Essa abordagem é ilustrada pelo método auxiliar na Listagem 4.
Listagem 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
A listagem 4 contém um módulo do Visual Basic que expõe dois métodos: RenderBanner() e RenderBannerInternal(). O método RenderBanner() representa o método auxiliar real. Esse método estende o padrão ASP.NET classe HtmlHelper MVC para que você possa chamar Html.RenderBanner() em uma exibição como qualquer outro método auxiliar.
O método RenderBanner() chama o método HttpResponse.WriteSubstitution() passando o método RenderBannerInternal() para o método WriteSubstitution().
O método RenderBannerInternal() é um método privado. Esse método não será exposto como um método auxiliar. O método RenderBannerInternal() retorna aleatoriamente uma imagem de anúncio de faixa de uma lista de três imagens de anúncio de faixa.
A exibição Índice modificada na Listagem 5 ilustra como você pode usar o método auxiliar RenderBanner(). Observe que uma diretiva %@ %> de importação adicional <está incluída na parte superior da exibição para importar o namespace MvcApplication1.Helpers. Se você não importar esse namespace, o método RenderBanner() não aparecerá como um método na propriedade Html.
Listagem 5 – Views\Home\Index.aspx (com o método 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>
Quando você solicita a página renderizada pela exibição na Listagem 5, um anúncio de faixa diferente é exibido com cada solicitação (consulte a Figura 2). A página é armazenada em cache, mas o anúncio de faixa é injetado dinamicamente pelo método auxiliar RenderBanner().
Figura 2 – a exibição Índice exibindo um anúncio de faixa aleatório
Resumo
Este tutorial explicou como você pode atualizar dinamicamente o conteúdo em uma página armazenada em cache. Você aprendeu a usar o método HttpResponse.WriteSubstitution() para permitir que o conteúdo dinâmico seja injetado em uma página armazenada em cache. Você também aprendeu a encapsular a chamada para o método WriteSubstitution() em um método auxiliar HTML.
Aproveite o cache sempre que possível – isso pode ter um impacto dramático no desempenho de seus aplicativos Web. Conforme explicado neste tutorial, você pode aproveitar o cache mesmo quando precisar exibir conteúdo dinâmico em suas páginas.