2009-12-28 25 views
5

Estoy intentando crear un menú para mi sitio web. Tiene que cumplir con los siguientes requisitosASP.Net MVC Menú basado en la base de datos con almacenamiento en caché

  • que debe ser conducido base de datos, extracción de datos de base de datos para construir la estructura de menús
  • que los datos sean extraídos de la base de datos necesita ser almacenado en caché - que no quieren golpear el DB 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 lo almacena en la 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 me tire de los datos de la ViewData y úsala para renderizar 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> 

luego 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 siempre que alguna de las acciones en mi controlador se ven afectados, la OnActionExecuted Se llamará al método en el ProductMenuAttribute class, que configurará ViewData, que eventualmente se usará en mi Site.Master para crear 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é.

+0

Para todos los fines relacionados con el código, este menú es estático, ¿no? ¿Por qué no creas una vista parcial que sabe acerca de una clase ProductMenu? Esto no eliminará su problema de almacenamiento en caché, pero se verá más limpio para un transeúnte como yo. Si tuviera que cambiar el menú, sé que pasaría horas averiguando cómo los productos entran en los viewdata. Probablemente no vería el [ProductMenu] aplicado a la clase de controlador. –

+0

Acepto que una vista parcial será más clara, pero mi ejemplo debe ser simplista. –

Respuesta

6

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, que generará la estructura del menú HTML al extraer los 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.

EDIT: Phil Haack ha escrito sobre esto recientemente - Html.RenderAction and Html.Action. Una gran publicación de blog que cubre todas mis necesidades exactas, con explicaciones de todos los problemas.

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

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

que luego llamar a la anterior con Html.RenderPartial(), y listo ¡Todo funciona!

0

He hecho esto utilizando el bloque de caché de Enterprise Library. Compruebe si hay datos almacenados en caché, si no hay datos almacenados en caché, crea cadena html a partir de los datos en su base de datos y póngalos en caché para luego buscar datos en caché, simplemente puede generar una cadena simple: D

Solo mencionar que el código para hacer eso 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.

Cuestiones relacionadas