Cache Tag Helper in ASP.NET Core MVC

Cache Tag Helper in ASP.NET Core MVC

I will discuss Cache Tag Helper in ASP.NET Core MVC Application with Examples in this article. Please read our previous article discussing View Component Tag Helper in ASP.NET Core MVC.

Cache Tag Helpers in ASP.NET Core MVC

The Cache Tag Helpers in ASP.NET Core MVC allow us to cache specific portions of our Razor views. This will help us to improve the performance by reducing the need to regenerate content on each request.

How to use Cache Tag Helpers in ASP.NET Core MVC?

Add the necessary namespace: Before we can use Cache Tag Helpers, ensure the following directive at the top of your Razor view, or you can also specify the same in the ViewImport.cshtml file. This will allow all the Tag helpers to be available in our view.

@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers

Use the Cache Tag Helper: Then you can use the <cache> tag helper to denote the portion of the view you want to cache as follows.

<cache>
    <!-- Your content to cache goes here. -->
</cache>

Attributes of the Cache Tag Helper:

  • expires-after: Duration for which the content should remain in the cache.
  • expires-on: An absolute expiration time for the content.
  • expires-sliding: A sliding expiration time.
  • vary-by: A comma-separated list of strings to vary the cache by. Useful when caching content that varies by certain conditions (like query string values, user agent, etc.).
  • vary-by-user: Caches content by user. When set to true, different users will have their own cached versions.
  • vary-by-cookie: Caches content based on the specified cookie name(s).
  • vary-by-header: Caches content based on the specified request header name(s).
  • vary-by-query: Caches content based on the specified query string parameter(s).

Here’s an example that uses some of these attributes:

<cache vary-by="@Context.Request.Query["id"]" vary-by-user="true" expires-after="@TimeSpan.FromMinutes(10)">
   <!-- Content that depends on the "id" query string parameter and user. -->
</cache>

Cache profiles: If you have multiple cache tags with similar settings, consider using cache profiles in Startup.cs (or Program.cs in .NET 6 and later). This allows you to centralize cache settings.

builder.Services.AddMvc(options =>
{
    options.CacheProfiles.Add("Default", new CacheProfile()
    {
        Duration = 60, // 1 minute
    });
});

Then, in your view:

<cache profile="Default">
   <!-- Cached content here -->
</cache>

Note: Cache content is stored in memory by default. You might want to consider distributed caching if your app restarts or runs in a web farm/load-balanced environment.

Caching should be done properly. Cache content that is relatively static or doesn’t change often. Over-caching or caching content that changes frequently can lead to outdated data being served to users. To cache data from your services or controllers, consider using built-in caching services like IMemoryCache or IDistributedCache, which we will discuss in our upcoming articles.

Cache Tag Helpers Examples in ASP.NET Core MVC:

Cache Tag Helpers in ASP.NET Core MVC provide a declarative way to add caching to your Razor views. Here are some practical examples to demonstrate its use. First, modify the Home Controller as follows.

using Microsoft.AspNetCore.Mvc;
namespace TagHelpersDemo.Controllers
{
    public class HomeController : Controller
    {
        public ViewResult Index()
        {
            return View();
        }
    }
}
Cache Attribute:

The Cache Tag Helper provides the ability to improve the performance of your ASP.NET Core app by caching its content to the internal ASP.NET Core cache provider. The following Razor markup caches the current date:

<cache>
    <p>This Content is Generated </p>
    Current Time Inside Cache Tag Helper: @DateTime.Now
</cache>

The first request to the page that contains the Tag Helper displays the current date. Additional requests show the cached value until the cache expires (default 20 minutes) or until the cached date is evicted from the cache.

Enabled Attribute:

The enabled Attribute of the Cache tag helper in ASP.NET Core MVC determines if the content enclosed by the Cache Tag Helper is cached. The default is true. If set to false, the rendered output is not cached.

<cache enabled="true">
    <p>This Content is Generated </p>
    Current Time Inside Cache Tag Helper: @DateTime.Now
</cache>
Expires-on Attribute:

The expires-on Attribute of Cache Tag Helper in ASP.NET Core MVC sets an absolute expiration date for the cached item. The following example caches the contents of the Cache Tag Helper until 05:15 AM on January 15, 2026:

<cache expires-on="@new DateTime(2026,1,15,05,15,0)">
    <p>This Content is Generated </p>
    Current Time Inside Cache Tag Helper: @DateTime.Now
</cache>
Expires-after:

The expires-after Attribute of Cache Tag Helper in ASP.NET Core MVC sets the time from the first request time to cache the contents. The following example caches a portion of the view for 10 minutes.

<cache expires-after="@TimeSpan.FromMinutes(10)">
    <p>This Content is Generated </p>
    Current Time Inside Cache Tag Helper: @DateTime.Now
</cache>

Every time you refresh the page within 10 minutes, you will notice the timestamp won’t change because the content is cached.

Expires-sliding Attribute

It is similar to expires-after, but the expiry will be renewed after every access. It is a TimeSpan type.

<cache expires-sliding="@TimeSpan.FromMinutes(10)">
    <p>This Content is Generated </p>
    Current Time Inside Cache Tag Helper: @DateTime.Now
</cache>
Vary-by-header Attribute:

The vary-by-header Attribute of Cache Tag Helper in ASP.NET Core MVC accepts a comma-delimited list of header values that trigger a cache refresh when they change. The following example monitors the header value User-Agent. The example caches the content for every different User-Agent presented to the web server.

<cache vary-by-header="User-Agent">
    <p>This Content is Generated </p>
    Current Time Inside Cache Tag Helper: @DateTime.Now
</cache>
Vary-by-query Attribute:

The vary-by-query Attribute of Cache Tag Helper in ASP.NET Core MVC accepts a comma-delimited list of Keys in a query string (Query) that triggers a cache refresh when the value of any listed key changes. The following example monitors the values of Name and ID. The example caches the content for every different Name and ID presented to the web server:

<cache vary-by-query="Name,Id">
    <p>This Content is Generated </p>
    Current Time Inside Cache Tag Helper: @DateTime.Now
</cache>
Vary-by-cookie Attribute:

The vary-by-cookie accepts a comma-delimited list of cookie names that trigger a cache refresh when the cookie values change. The following example monitors the cookie associated with ASP.NET Core Identity. When a user is authenticated, a change in the Identity cookie triggers a cache refresh:

<cache vary-by-cookie=".AspNetCore.Identity.Application">
    <p>This Content is Generated </p>
    Current Time Inside Cache Tag Helper: @DateTime.Now
</cache>
Vary-by-user Attribute:

The vary-by-user specifies whether or not the cache resets when the signed-in user (or Context Principal) changes. The current user is also known as the Request Context Principal and can be viewed in a Razor view by referencing @User.Identity.Name. The following example monitors the current logged-in user to trigger a cache refresh:

<cache vary-by-user="true">
    Welcome, @User.Identity.Name! Your personalized content is here.
    Current Time Inside Cache Tag Helper: @DateTime.Now
</cache>

This attribute maintains the contents in the cache through a sign-in and sign-out cycle. When the value is set to true, an authentication cycle invalidates the cache for the authenticated user. The cache is invalidated because a new unique cookie value is generated when a user is authenticated. The cache is maintained for the anonymous state when no cookie is present, or the cookie has expired. If the user is not authenticated, the cache is maintained.

Vary-by Attribute:

The vary-by Attribute of Cache Tag Helper in ASP.NET Core MVC allows to customize what data is cached. When the object referenced by the attribute’s string value changes, the content of the Cache Tag Helper is updated.

The following example assumes the controller method rendering the view sums the integer value of the two route parameters, myParam1 and myParam2, and returns the sum as the single model property. When this sum changes, the content of the Cache Tag Helper is rendered and cached again. So, first, modify the Home Controller as follows:

using Microsoft.AspNetCore.Mvc;
namespace TagHelpersDemo.Controllers
{
    public class HomeController : Controller
    {
        public IActionResult Index(string myParam1, string myParam2)
        {
            int num1;
            int num2;
            int.TryParse(myParam1, out num1);
            int.TryParse(myParam2, out num2);
            return View("Index", num1 + num2);
        }
    }
}

Next, modify the Index.cshtml view as follows:

@model int

<cache vary-by="@Model">
    <p>Result : @Model</p>
    Current Time Inside Cache Tag Helper: @DateTime.Now
</cache>
Vary by Query String

Cache content based on a specific query string value. For different category query string values, different cached content will be stored.

<cache vary-by="@Context.Request.Query["category"]">
    Showing products for category: @Context.Request.Query["category"]
    <br/>
    Current Time Inside Cache Tag Helper: @DateTime.Now
</cache>
Using Cache Profile

First, define a cache Profile in your Program.cs class file as follows. Here, we define the cache profile, which will cache the data for 1 minute.

builder.Services.AddControllersWithViews(options =>
{
    options.CacheProfiles.Add("ShortLivedCache", new CacheProfile()
    {
        Duration = 60 // 1 minute
    });
});

After defining a cache profile in your Program.cs class, then use it in your Razor view. So, modify the Index.cshtml view as follows:

<cache profile="ShortLived">
    <p>
        Cached content using the ShortLived profile.
    </p>
    Current Time Inside Cache Tag Helper: @DateTime.Now
</cache>
Real-Time Examples of Cache Tag Helpers in ASP.NET Core MVC

Let us see some examples to understand the application of Cache Tag Helpers in ASP.NET Core MVC:

1. E-Commerce Site Product Listing:

On an e-commerce site, products can be filtered by category. Given the vast number of products, fetching each category from the database every time would be inefficient.

<cache vary-by="@Context.Request.Query["category"]" expires-after="@TimeSpan.FromMinutes(15)">
    @* Display products for the category fetched from the database *@
</cache>
2. Blog Post Comments:

While the post might change infrequently for a blogging website, the comments section below can be updated more often.

<!-- Cache the blog post content -->
<cache key="BlogPost-@Model.PostId" expires-after="@TimeSpan.FromHours(2)">
    @Html.Raw(Model.PostContent)
</cache>

<!-- Cache the comments section separately -->
<cache key="BlogPostComments-@Model.PostId" expires-after="@TimeSpan.FromMinutes(10)">
    @foreach(var comment in Model.Comments) {
        <div>@comment.Text</div>
    }
</cache>
3. Weather Widget:

A site might have a sidebar widget showing the current weather. This doesn’t need to be real-time, but fetching it every minute would be excessive.

<cache key="WeatherWidget" expires-after="@TimeSpan.FromMinutes(30)">
    @* Fetch and display the weather for the current city *@
</cache>
4. User Profile Summary:

A user dashboard displays a summary of the user’s profile, including some statistics.

<cache vary-by-user="true" expires-after="@TimeSpan.FromHours(1)">
    Welcome, @User.Identity.Name!
    You have @Model.FriendsCount friends and @Model.PostsCount posts.
</cache>
5. Top News Stories:

Top stories can be cached for a news portal, as they may not change every minute.

<cache key="TopNewsStories" expires-after="@TimeSpan.FromMinutes(20)">
    @* Display top 5 news stories fetched from the database or API *@
</cache>
6. Trending Products or Posts:

Websites often display trending items which are updated every few hours.

<cache key="TrendingProducts" expires-after="@TimeSpan.FromHours(4)">
    @* Display top trending products based on sales or views *@
</cache>
7. User-specific Recommendations:

On platforms like streaming sites or e-commerce, user-based recommendations are key. They don’t change every minute but are specific to each user.

<cache vary-by-user="true" expires-after="@TimeSpan.FromHours(3)">
    @* Display personalized content recommendations for the logged-in user *@
</cache>
Use Cases of Cache Tag Helpers in ASP.NET Core MVC:

Cache Tag Helpers in ASP.NET Core MVC can significantly improve the responsiveness and scalability of web applications by temporarily storing (caching) content to avoid its expensive or redundant generation. Here are some practical use cases:

  • Static Content with Occasional Updates: Suppose you have a news or blog section where updates are not frequent. Cache Tag Helpers can cache these sections to reduce database lookups.
  • User-specific Content: Personalized greetings, dashboard snippets, or profile summaries are ideal for caching with vary-by-user so each user sees their own cached version.
  • High-Traffic Pages: Caching certain sections can significantly reduce server load for high-traffic, public-facing pages (like a website’s homepage).
  • Dynamic Content Based on Query Parameters: Product listings filtered and sorted by query parameters (e.g., ?category=electronics&sort=price-asc) can be cached based on those parameters using vary-by.
  • Content Based on Geolocation or User-Agent: Displaying content tailored to the user’s device type (desktop, mobile, tablet) or region? Cache distinct versions for each scenario.
  • SEO & Meta Information: If your site’s SEO meta tags are generated based on dynamic content, caching these can reduce database or API calls.
  • Ratings & Reviews: Displaying average ratings or the latest reviews? If calculating averages or fetching reviews is costly, consider caching this section.
  • E-Commerce Sites: Bestsellers, recommended products, or recently viewed items sections on e-commerce sites can be cached for better performance.
  • Interactive Widgets: Widgets like polls, quizzes, or surveys where data doesn’t change frequently can benefit from caching.
  • Third-Party Integrations: Displaying tweets, weather information, stock prices, or other third-party data? Cache them to avoid hitting third-party rate limits and reduce load times.

Points to Remember when working with Caching:

  • Be cautious with caching. Ensure that any content you cache won’t pose a security or privacy risk if shown to the wrong user.
  • Test your caching logic to ensure it works as expected, especially when using multiple vary-by parameters.
  • Remember that the default caching mechanism is in-memory. If you need a more persistent or distributed cache, consider integrating with a distributed caching solution like Redis.

In the next article, I will discuss Model Binding in ASP.NET Core MVC Application. Here, in this article, I try to explain Cache Tag Helper in ASP.NET Core MVC Application with Examples. I hope you enjoy this Cache Tag Helper in ASP.NET Core article.

Leave a Reply

Your email address will not be published. Required fields are marked *