asp.net-mvc caching menu database-driven

ASP.Net MVC Menú basado en la base de datos con almacenamiento en caché



asp.net-mvc caching (3)

Estoy tratando de crear un menú para mi sitio web. Necesita cumplir con los siguientes requisitos

  • debe ser manejado por bases de datos, extrayendo datos de DB para construir la estructura del menú
  • los datos que se extraen de la base de datos deben almacenarse en caché; no deseo acceder a la base de datos para cada solicitud de página

Por el momento, tengo un ejemplo simplista en ejecución, pero no sé cómo integrar el almacenamiento en caché. Creo que debería volver a trabajar todo el tiempo que hago esto. Aquí está:

Tengo un ProductMenuAttribute , que extrae los datos de la base de datos y los almacena en ViewData:

public class ProductMenuAttribute: FilterAttribute, IActionFilter { #region IActionFilter Members public void OnActionExecuted(ActionExecutedContext filterContext) { if (filterContext != null) { var context = filterContext.Result as ViewResult; if (context != null) { ProductsRepository repository = new ProductsRepository(Properties.Settings.Default.SqlConnectionString); context.ViewData.Add("ProductsList", repository.GetAllProductRanges()); } } } public void OnActionExecuting(ActionExecutingContext filterContext) { } #endregion }

En mi Site.master , extraigo los datos de ViewData y los utilizo para representar mi menú. Este es un pequeño fragmento en mi lista de menú no ordenada, que se personaliza con CSS. Aquí está el código:

<li> <%= Html.ActionLink("Products", "Index", "Products")%> <% IQueryable<ProductRange> productRanges = ViewData["ProductsList"] as IQueryable<ProductRange>; %> <% if (productRanges != null) { %> <ul> <% foreach (ProductRange range in productRanges) { %> <li><%= Html.ActionLink(range.Name, "RangeDetails", "Products", new { id = range.ID }, null)%></li> <% } %> </ul> <% } %> </li>

A continuación, decorar cada controlador con el [ProductMenu] attribuate de la siguiente manera:

[ProductMenu] public class HomeController : BaseController { public ActionResult Index() { return View(); } public ActionResult About() { return View(); } }

Ahora, cada vez que se acciona alguna de las acciones en mi controlador, se llamará al método OnActionExecuted en la clase ProductMenuAttribute , que configurará ViewData, que eventualmente se usará en mi Site.Master para construir mi menú desde el DB, a qué hora Llamo a cualquiera de las acciones.

El problema ahora es: ¿cómo agrego el almacenamiento en caché a este escenario? No tengo ni idea de por dónde empezar, y tengo la sensación de que la solución que tengo no es almacenable en caché.


Creo que lo que realmente estoy buscando es utilizar la extensión de ayuda Html.RenderAction () del proyecto MVC Futures.

La idea es utilizar lo anterior para llamar a una acción en un controlador, lo que generará la estructura del menú HTML extrayendo datos del DB. Luego también utilizo el almacenamiento en caché de salida simple para almacenar en caché los datos durante unos minutos.

Este es el enfoque más simple que he encontrado hasta ahora para lograr lo que quiero.

EDITAR: Phil Haack blogueó sobre este recientemente - Html.RenderAction y Html.Action . Una gran publicación de blog que cubre todas mis necesidades exactas, con explicaciones de todos los problemas.

Para que el almacenamiento en caché funcione correctamente, tendría que poner mi llamada Html.RenderAction() dentro de un ViewUserControl con la directiva OutputCaching establecida de la siguiente manera:

<@ OutputCache Duration="100" VaryByParam="None" %>

Luego llamo a lo de arriba con Html.RenderPartial() , y listo, ¡todo funciona!


Lo he hecho utilizando el bloque Enterprise Enterprise Caching. Verificas los datos almacenados en caché, si no hay datos en caché, creas una cadena html a partir de datos en tu base de datos y la colocas en el caché para luego, al buscar datos almacenados en caché, puedes simplemente generar una cadena simple: D

Solo mencionar que el código para hacerlo estaba en la clase estática. Voy a publicar un ejemplo pero estoy reescribiendo esa aplicación en MVC2 desde cero, así que no tengo el código a mano.