procesos costosos.
En versiones anteriores a ASP.NET 5, siempre podíamos acceder a objeto
Cache
de ASP.NET, disponible en el contexto de la petición, o a los componentes presentes en System.Web.Caching
y crear nuestras soluciones personalizadas, pero realmente MVC no aportaba más ayudas de serie que el filtro [OutputCache]
. Su objetivo era cachear el resultado de acciones durante un tiempo determinado y reutilizarlo en peticiones siguientes, lo que era suficiente para muchos escenarios pero complicaba un poco otras necesidades comunes, como el cacheo de porciones de páginas.Pero antes de continuar, un par de avisos:
- Si aún no sabes lo que es un tag helper, ya estás tardando en leer este post ;)
- ASP.NET se encuentra aún en desarrollo, por lo que parte de lo expuesto a continuación podría variar en la versión final del producto.
<cache>
. El resultado de renderizar su contenido será cacheado en el servidor y reutilizado las siguientes ejecuciones de la vista, hasta que la caché expire por las condiciones que hayamos indicado.Veamos un ejemplo de la forma más simple que tenemos de utilizar este tag helper en una vista:
<h2>Current: @DateTime.Now.ToString("hh:mm:ss"))</h2> <cache expires-after="TimeSpan.FromSeconds(30)"> <h2>Cached: @DateTime.Now.ToString("hh:mm:ss")</h2> </cache>Hay varios aspectos interesantes en este código. Primero, observad que este tag helper define una etiqueta nueva, a diferencia de otros que hemos visto, como
AnchorTagHelper
para construir enlaces <a>
. Debido a ello, no hay necesidad de distinguir sus parámetros con un prefijo, como los habituales "asp-" que vemos en otros tag helpers que modifican etiquetas existentes.Otro aspecto a destacar es que hemos especificado el valor del parámetro
expires-after
directamente mediante una expresión C#, sin necesidad de utilizar el carácter de escape "@" de Razor. Esto es así porque el parser ha detectado que la propiedad subyacente es de tipo TimeSpan
, por lo que directamente espera que codifiquemos ahí una expresión de este tipo, y el entorno puede ayudarnos con el imprescindible intellisense.Si accedemos a esta vista y refrescamos la página segundos más tarde, el resultado que tendremos es el siguiente. Como podemos ver, el bloque del interior de
<cache>
no será evaluado de nuevo hasta pasados los 30 segundos que hemos indicado en el parámetro expires-after
, retornando en su lugar el resultado que fue cacheado anteriormente:
Ejecución inicial
|
Tras refrescar la página
|
Otro ejemplo. En este caso, la primera ejecución de la página durará cinco segundos, pero tras ella todas las demás retornarán inmediatamente el contenido cacheado sin necesidad de ejecutar nada:
<cache expires-after="TimeSpan.FromMinutes(10)"> @{ await Task.Delay(5000); } <h2>Cached: @DateTime.Now.ToString("hh:mm:ss")</h2> </cache>La etiqueta
<cache>
tiene parámetros que permiten configurar su comportamiento de forma muy similar al filtro [OutputCache]
, y que seguro que os son familiares:- Parámetros para indicar la duración del caché:
expires-after
, visto anteriormente en los ejemplos, indica el tiempo de validez del caché desde que se almacena su contenido.expires-sliding
, contiene unTimeSpan
que indica el tiempo en que el caché caducará tras haber accedido a su contenido por última vez.expires-on
, un valorDateTimeOffset
que indica en términos absolutos cuándo expirará el contenido cacheado.
<cache expires-sliding="TimeSpan.FromSeconds(30)"> <h2>Cached: @DateTime.Now.ToString("hh:mm:ss")</h2> </cache>
- Parámetros que indican qué factores actúan como criterios de discriminación a la hora de salvar o recuperar valores de la caché. Esto es bastante útil si queremos cachear porciones de página para determinado grupo de usuarios o peticiones:
var-by
, permite que el caché varíe dependiendo del valor alfanumérico arbitrario del mismo.var-by-header
, nombre del encabezado HTTP que variará el caché.var-by-query
, una lista de parámetros del query string, separados por comas, que actuarán como discriminador.
<cache expires-after="TimeSpan.FromMinutes(10)" var-by-query="searchTerm"> <h2>Search results:</h2> <ul> @foreach(var product in Products) { <li>@product.Name<li> } </ul> </cache>
var-by-route
, una lista de parámetros de ruta que actuarán como discriminador.var-by-cookie
, lista de nombres de cookies separados por comas, que actuarán como disvar-by-user
, un booleano que indica si el valor de la caché debe variar en función de la identidad del usuario conectado.
<cache expires-after="TimeSpan.FromMinutes(10)" var-by-user="true"> <h2>Hello, @User.Identity.Name </h2> </cache>
- Parámetros generales de comportamiento:
priority
, un valorCacheItemPriority
que indica la prioridad del contenido en situaciones de escasa memoria.enabled
, que si establecemos a "false" permite desactivar el caché, forzando a que se procese el contenido del tag<cache>
como si no existiera. Esto puede ser útil, por ejemplo, para depurar una página:
<cache expires-after="TimeSpan.FromMinutes(10)" enabled="false"> <h2>Cached: @DateTime.Now.ToString("hh:mm:ss")</h2> </cache>
vary-by-cookie
, vary-by-query
o vary-by-route
.Ah, y una última cosa: al menos de momento,
CacheTagHelper
usa internamente para almacenar el caché una instancia de IMemoryCache
, por lo que el contenido no puede ser distribuido o enviado a un almacenamiento externo como Redis o SQL Server, ni será persistente si el servidor sufre algún tropezón.Publicado en Variable not found.
from Variable not found http://www.variablenotfound.com/2015/10/cacheo-de-porciones-de-vistas-en-mvc-6.html
via IFTTT