Compartilhar via


Adicionar conteúdo dinâmico a uma página em cache (C#)

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 em 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 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, chame 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.cs

using System;
using System.Collections.Generic;
using System.Web;

namespace MvcApplication1.Models
{
    public class News
    {
        public static string RenderNews(HttpContext context)
        {
            var news = new List<string> 
                { 
                    "Gas prices go up!", 
                    "Life discovered on Mars!", 
                    "Moon disappears!" 
                };
            
            var rnd = new Random();
            return news[rnd.Next(news.Count)];
        }
    }
}

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 por conteúdo dinâmico. O método WriteSubstitution() é usado para exibir o item de notícias aleatório no modo de exibição na Listagem 2.

Listagem 2 – Views\Home\Index.aspx

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Index.aspx.cs" Inherits="MvcApplication1.Views.Home.Index" %>
<%@ Import Namespace="MvcApplication1.Models" %>
<!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 runat="server">
    <title>Index</title>
</head>
<body>
    <div>

    <% Response.WriteSubstitution(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 (não há parênteses). Em vez disso, uma referência ao método é passada para WriteSubstitution().

A exibição Índice é armazenada em cache. O modo de exibição é retornado 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.cs

using System.Web.Mvc;

namespace MvcApplication1.Controllers
{
    [HandleError]
    public class HomeController : Controller
    {
        [OutputCache(Duration=60, VaryByParam="none")]
        public ActionResult Index()
        {
            return View();
        }
    }
}

Embora a exibição Índice esteja 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

clip_image002

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 – AdHelper.cs

using System;
using System.Collections.Generic;
using System.Web;
using System.Web.Mvc;

namespace MvcApplication1.Helpers
{
    public static class AdHelper
    {
        public static void RenderBanner(this HtmlHelper helper)
        {
            var context = helper.ViewContext.HttpContext;
            context.Response.WriteSubstitution(RenderBannerInternal);
        }
        
        private static string RenderBannerInternal(HttpContext context)
        {
            var ads = new List<string> 
                { 
                    "/ads/banner1.gif", 
                    "/ads/banner2.gif", 
                    "/ads/banner3.gif" 
                };

            var rnd = new Random();
            var ad = ads[rnd.Next(ads.Count)];
            return String.Format("<img src='{0}' />", ad);
        }
    }
}

A listagem 4 contém uma classe estática 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 em faixa.

A exibição Índice modificada na Listagem 5 ilustra como você pode usar o método auxiliar RenderBanner(). Observe que uma <diretiva %@ adicional de %> de importação 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="C#" AutoEventWireup="true" CodeBehind="Index.aspx.cs" Inherits="MvcApplication1.Views.Home.Index" %>
<%@ Import Namespace="MvcApplication1.Models" %>
<%@ Import Namespace="MvcApplication1.Helpers" %>
<!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 runat="server">
    <title>Index</title>
</head>
<body>
    <div>

    <% Response.WriteSubstitution(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 pelo modo de 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ória

clip_image004

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.