Caching on MVC sites

Caching is an important factor of your MVC website’s overall performance. With Xperience, 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 Xperience database and display on the site (see Retrieving content for more information).

For pages, custom table data or forms, you can handle the caching in individual repositories that make use of the API. 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 class or the IProgressiveCache service 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 = () => new DocumentQuery<Article>()
            .OnSite(siteName)
            .Culture(culture)
            .TopN(count)
            .OrderByDescending("DocumentPublishFrom")
            .ToList(); // 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 Xperience.
            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 = () => new DocumentQuery<Article>()
                                                        .WithGuid(nodeGuid)
                                                        .Culture(culture)
                                                        .OnSite(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 Xperience (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 Xperience.
    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

You can use the debugging tools in the Xperience administration interface to inspect the MVC application’s cache.

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).

Clearing the cache

To delete all data from the cache of your live site, you need to restart the application.

You can use the Xperience administration interface to restart all applications connected to the same database:

  1. Open the System application.
  2. On the General tab, click Restart all web farm servers.

Note: The Clear cache button in the System application only deletes the cache of the administration application, not the live site.