Caching on MVC sites

Caching is an important factor of your MVC website’s overall performance. With Kentico, you can set up and configure the following types of caching:

Caching data

We recommend caching data in the code of your MVC site, particularly for data that is frequently accessed (queried from the database). For example, you may want to cache page or form data that you retrieve from the Kentico database and display on the site (see Retrieving content in MVC applications for more information).

For pages, custom table data or forms, you can handle the caching in individual repositories that make use of the generated providers. Another approach would be using AOP and decorating individual repositories – see the code of the Dancing Goat MVC sample site for a reference on how to use this approach.

Use the CacheHelper.Cache method to cache data in your code. See Caching in custom code for general information about the caching API.

Examples

Notes

  • To ensure consistency of the viewed data, always generate cache keys with names that include all the parameters that you use to retrieve the data. For example, a culture code variable in the cache key for page data ensures that visitors do not see cached articles displayed in an old culture after switching to a new culture.
  • The examples use minimal cache dependencies. See Setting cache dependencies for more information on how to configure cache dependencies for your scenarios.
Caching the data of multiple articles



using System;
using System.Collections.Generic;
using System.Linq;

using CMS.Helpers;
using CMS.SiteProvider;

...

public IEnumerable<Article> GetArticles(int count = 0)
{
    string culture = "en-us";
    string siteName = SiteContext.CurrentSiteName;

    Func<IEnumerable<Article>> dataLoadMethod = () => ArticleProvider.GetArticles()
            .OnSite(siteName)
            .Culture(culture)
            .TopN(count)
            .OrderByDescending("DocumentPublishFrom")
            .TypedResult; // Ensures that the result of the query is saved, not the query itself

    var cacheSettings = new CacheSettings(10, "myapp|data|articles", siteName, culture, count)
    {
        GetCacheDependency = () =>
        {
            // Creates caches dependencies. This example makes the cache clear data when any article is modified, deleted, or created in Kentico.
            string dependencyCacheKey = String.Format("nodes|{0}|{1}|all", siteName, Article.CLASS_NAME.ToLowerInvariant());
            return CacheHelper.GetCacheDependency(dependencyCacheKey);
        }
    };

    return CacheHelper.Cache(dataLoadMethod, cacheSettings);
}


Caching the data of a single article



using System;
using System.Linq;

using CMS.Helpers;
using CMS.SiteProvider;

...

public Article GetArticle(Guid nodeGuid)
{
    string culture = "en-us";
    string siteName = SiteContext.CurrentSiteName;

    Func<Article> dataLoadMethod = () => ArticleProvider.GetArticle(nodeGuid, culture, siteName)
                                                        .TopN(1)
                                                        .FirstOrDefault();

    var cacheSettings = new CacheSettings(10, "myapp|data|article", nodeGuid, culture, siteName)
    {
        GetCacheDependency = () =>
        {
            // Creates cache dependencies. This example makes the cache clear the data when the specified article is modified in Kentico (any culture version).
            string dependencyCacheKey = String.Format("nodeguid|{0}|{1}", siteName, nodeGuid);
            return CacheHelper.GetCacheDependency(dependencyCacheKey);
        }
    };

    return CacheHelper.Cache(dataLoadMethod, cacheSettings);
}


Caching the output of controller actions

You can cache the output of individual controller actions using ASP.NET output caching. This can significantly increase your website performance. We recommend caching the output of all possible controller actions, especially for controllers that return often requested views.

Use the OutputCache attribute to mark the action methods you want to cache. Set the cache duration (in seconds) and other properties of the attribute.

Output cache dependencies

When storing the output cache on the server (OutputCache attribute’s Location property is set to Server), you can define cache dependencies to accommodate various scenarios with both static and dynamic content. Use the HttpContext.Response.AddCacheItemDependency method to add dependencies on memory cache items in individual controller action methods. When these items are touched, the system automatically invalidates the output cache for the corresponding controller action as well.

The used cache dependency keys (dummy cache items) must be fully in lower case. If necessary, convert any dynamic parameters or variables within the dependency keys to lower case before you add them to the HTTP response.

Controller actions can be called in situations in which the dummy cache items have not yet been created. To account for that, ensure the existence of the dummy cache item explicitly by calling the CacheHelper.EnsureDummyKey method. The method also automatically converts the provided key to lower case before inserting it into the cache.

Caching personalized content

When caching the output of actions serving personalized content – tailored content served based on a visitor’s persona, assigned contact group, or other on-line marketing features – you need to manually adjust the output cache behavior by configuring the set of variables under which the content is cached.

See Caching the output of personalized content.

Example




using System;
using System.Web.UI;
using System.Web.Mvc;

using CMS.Helpers;

...

[OutputCache(Duration=600, VaryByParam="None", Location = OutputCacheLocation.Server)]
public ActionResult Index()
{
    var articles = mArticleRepository.GetArticles();

    // Sets cache dependencies. This example makes the system clear the cache when any article is modified in Kentico.
    string dependencyCacheKey = String.Format("nodes|mvcsite|{0}|all", Article.ClassName.ToLowerInvariant());
    // Converts the provided key to lower case and inserts it into the cache
    CacheHelper.EnsureDummyKey(dependencyCacheKey);
    HttpContext.Response.AddCacheItemDependency(dependencyCacheKey);

    return View(articles);
}


Notes:

  • If the resulting view contains a form with smart fields (as part of its page builder configuration), all output caching functionality is automatically disabled by the system.
  • ASP.NET output caching is disabled for requests where you explicitly set cookies for the visitor’s browser (for example using the Set-Cookie HTTP response header).
  • The example uses minimal cache dependencies – the cache is cleared when any of the articles the method works with is modified, deleted, or when a new article is created. See Setting cache dependencies for more information on how to configure cache dependencies for your scenarios.
  • Use the Html.Kentico().AntiForgeryToken() method (Kentico.Web.Mvc namespace) in forms on cached pages instead of the default Html.AntiForgeryToken() provided by the .NET framework. The method ensures that anti-forgery tokens are correctly generated for pages under output caching.

Cache debugging

Because the MVC site runs as a separate application with its own memory, you cannot use the cache debugging tools in the Kentico administration interface for MVC scenarios.

For the standard ASP.NET output cache, you can use third-party debugging tools (for example the Glimpse tool and the Glimpse.AspNet NuGet package).