Compartir a través de


Agregar contenido dinámico a una página almacenada en caché (C#)

por Microsoft

Aprenda a mezclar contenido dinámico y almacenado en caché en la misma página. La sustitución posterior a la caché permite mostrar contenido dinámico, como anuncios de banner o elementos de noticias, dentro de una página que se ha almacenado en caché en la salida.

Conel almacenamiento en caché de salida, puede mejorar drásticamente el rendimiento de una aplicación ASP.NET MVC. En lugar de volver a generar una página una y otra vez cada que se solicita, se puede generar una vez y almacenarse en caché en la memoria para varios usuarios.

Pero hay un problema. ¿Qué ocurre si necesita mostrar contenido dinámico en la página? Por ejemplo, imagine que desea mostrar un anuncio de banner en la página. No quiere que el anuncio de banner se almacene en caché y que todos los usuarios vean el mismo anuncio. ¡No ganaría dinero de esa manera!

Afortunadamente, hay una solución fácil. Puede usar una característica del marco ASP.NET denominada sustitución posterior a la caché. La sustitución posterior a la caché permite sustituir el contenido dinámico de una página que se ha almacenado en caché en la memoria.

Normalmente, cuando se genera una caché de una página mediante el atributo [OutputCache], la página se almacena en caché tanto en el servidor como en el cliente (el explorador web). Cuando se usa la sustitución posterior a la caché, una página solo se almacena en caché en el servidor.

Uso de la sustitución posterior a la caché

El uso de la sustitución posterior a la caché requiere dos pasos. En primer lugar, debe definir un método que devuelva una cadena que represente el contenido dinámico que desea mostrar en la página almacenada en caché. A continuación, llamará al método HttpResponse.WriteSubstitution() para insertar el contenido dinámico en la página.

Imagine, por ejemplo, que desea mostrar aleatoriamente diferentes elementos de noticias en una página almacenada en caché. La clase de la lista 1 expone un único método, denominado RenderNews(), que devuelve aleatoriamente un elemento de noticias de una lista de tres elementos de noticias.

Lista 1: Modelos\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 usar la sustitución posterior a la caché, llamará al método HttpResponse.WriteSubstitution(). El método WriteSubstitution() configura el código para reemplazar una región de la página almacenada en caché por contenido dinámico. El método WriteSubstitution() se usa para mostrar el elemento de noticias aleatorio en la vista de la lista 2.

Lista 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>

El método RenderNews se pasa al método WriteSubstitution(). Observe que no se llama al método RenderNews (no hay paréntesis). En su lugar, se pasa una referencia al método WriteSubstitution().

La vista Index está almacenada en caché. El controlador devuelve la vista en la lista 3. Observe que la acción Index() está decorada con un atributo [OutputCache] que hace que la vista Index se almacene en caché durante 60 segundos.

Lista 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();
        }
    }
}

Aunque la vista Index está almacenada en caché, al solicitar la página Index, se muestran diferentes elementos de noticias aleatorios. Al solicitar la página Index, la hora mostrada por la página no cambia durante 60 segundos (vea la figura 1). El hecho de que la hora no cambie demuestra que la página está almacenada en caché. Sin embargo, el contenido insertado por el método WriteSubstitution() – el elemento de noticias aleatorio – cambia con cada solicitud.

Figura 1: Inserción de elementos de noticias dinámicos en una página almacenada en caché

clip_image002

Uso de la sustitución posterior a la caché en métodos auxiliares

Una manera más fácil de usar la sustitución posterior a la caché consiste en encapsular la llamada al método WriteSubstitution() dentro de un método auxiliar personalizado. Este enfoque se ilustra mediante el método auxiliar en la lista 4.

Lista 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);
        }
    }
}

La lista 4 contiene una clase estática que expone dos métodos: RenderBanner() y RenderBannerInternal(). El método RenderBanner() representa el método auxiliar real. Este método extiende la clase estándar HtmlHelper de ASP.NET MVC para que pueda llamar a Html.RenderBanner() en una vista igual que cualquier otro método auxiliar.

El método RenderBanner() llama al método HttpResponse.WriteSubstitution() pasando el método RenderBannerInternal() al método WriteSubstitution().

El método RenderBannerInternal() es un método privado. Este método no se expondrá como método auxiliar. El método RenderBannerInternal() devuelve aleatoriamente una imagen de anuncio de banner de una lista de tres imágenes de anuncios de banner.

La vista Index modificada de la lista 5 muestra cómo puede usar el método auxiliar RenderBanner(). Observe que se incluye una directiva <%@ Import %> adicional en la parte superior de la vista para importar el espacio de nombres MvcApplication1.Helpers. Si no importa este espacio de nombres, el método RenderBanner() no aparecerá como método en la propiedad Html.

Lista 5: Views\Home\Index.aspx (con el 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>

Al solicitar la página representada por la vista de la lista 5, se muestra un anuncio de banner diferente con cada solicitud (vea la figura 2). La página se almacena en caché, pero el método auxiliar RenderBanner() inserta dinámicamente el anuncio de banner.

Figura 2: La vista Index muestra un anuncio de banner aleatorio

clip_image004

Resumen

En este tutorial se explica cómo actualizar dinámicamente el contenido en una página almacenada en caché. Ha aprendido a usar el método HttpResponse.WriteSubstitution() para permitir que el contenido dinámico se inserte en una página almacenada en caché. También ha aprendido a encapsular la llamada al método WriteSubstitution() dentro de un método auxiliar HTML.

Aproveche las ventajas del almacenamiento en caché siempre que sea posible: puede tener un efecto considerable en el rendimiento de las aplicaciones web. Como se explica en este tutorial, puede aprovechar las ventajas del almacenamiento en caché incluso cuando necesite mostrar contenido dinámico en las páginas.