Response Caching In ASP.NET Core

Introduction

Response Caching adds a cache-related header into the response when the action, controller, or middle layer is decorated with the ResponseCache attribute. Unlike Output cache, it does not store HTTP response on the server, it just adds a "Cache-Control" header in the response. It helps us to reduce the number of requests made by the client or proxy to the Web Server. It also helps to improve the performance of the Web Server by reducing the amount of work done by the web server to generate the response. The "Cache-Control" header is used by the HTTP header.

The following common cache directives are used by the HTTP header.

  • Public
  • Private
  • No-cache
  • Pragma
  • Vary

Following are some properties of the ResponseCache attribute.

  • Duration It is the maximum time in seconds the response will be cached. If it is not working, no store property is set to true.
  • Location It is the place where the cache response might be stored. The default value is Any.
  • NoStore Based on the value of this property, the cache mechanism decides whether the cache is stored or not. When it is set to true, then Duration and Location are ignored.
  • VaryByHeader Any value set to this property will be written with the response. If the header value has changed, the cache version becomes invalid.
  • CacheProfileName Cache profile name that is used to do response cache.
  • Order The order of the filter.

The value of the Cache-Control header could be Public, Private, no-cache, Pragma, and vary. Let’s discuss each one of them. I am using Fiddler to check the response to the request in this article.

Public

The public response directive indicates that it allows to cache of any caching mechanism. This directive can be used when our page is independent of the user; i.e., the same page is available for all users, such as a static help page.

Controller’s Action method

[ResponseCache(Duration = 60)]  
[Route("home/LogData")]  
public IActionResult LogData() {  
    return View();  
}  

Output

Cache

Private

The "private" value for the Cache-Control header indicates that the value for the response message is intended for a single user. It is not stored in a shared cache. To make it private, we need to specify "Location = ResponseCacheLocation.Client" along with the ResponseCachen attribute.

Controller’s Action method

[ResponseCache(Duration = 60, Location = ResponseCacheLocation.Client)]  
[Route("home/LogData1")]  
public IActionResult LogData1() {  
    return View("LogData");  
}  

Output

Headers

No-cache

The "no-cache" request directive indicates that the cache has not stored any part of either response or request. To make it no-cache, we need to specify "Location = ResponseCacheLocation.None" along with the ResponseCachen attribute. 

Controller’s Action method

[ResponseCache(Duration = 60, Location = ResponseCacheLocation.None)]  
[Route("home/LogData2")]  
public IActionResult LogData2() {  
    return View("LogData");  
}  

Output

Cache

Pragma

This header field allows backward compatibility with HTTP/1.0 caches, so if the client sets a "no-cache" header, they will understand. This header is ignored when Cache-Control is present in the header.

Vary

The header is set only when the VaryByHeader property is set. It contains the comma-separated values that are used to vary the cache entry. When this property contains comma-separated values, the cache may have different versions of the cache value.

Controller’s Action method

[ResponseCache(Duration = 60, VaryByHeader = "User-Agent")]  
[Route("home/LogData3")]  
public IActionResult LogData3() {  
    return View("LogData");  
}  

Output

User agent

Configure the response cache by using the CacheProfileName property

As described above, we can configure the response cache for the controller action method. Instead of defining response cache for individual action i.e. duplicating cache setting, we can use cache profiles to configure as options in the ConfigureServices method in the startup class. Property value defined in the cache profile will be used as the default and if any property is defined with ResponseCache, the attribute will be the overridden property value defined in the cache profile.

In the following example, I have defined two cache profiles “default” and “Mycache”. In the Home Controller, I have used the “MyCache” profile for cache response.

Startup.cs

using Microsoft.AspNetCore.Builder;  
using Microsoft.AspNetCore.Hosting;  
using Microsoft.AspNetCore.Http;  
using Microsoft.AspNetCore.Mvc;  
using Microsoft.Extensions.DependencyInjection;  
namespace WebApplication {  
    public class Startup {  
        public void Configure(IApplicationBuilder app, IHostingEnvironment env) {  
            app.UseMvc();  
            app.UseResponseCaching();  
            app.Run(context => {  
                return context.Response.WriteAsync("Hello Readers!");  
            });  
        }  
        public void ConfigureServices(IServiceCollection services) {  
            services.AddMvc((options) => {  
                options.CacheProfiles.Add("default", new CacheProfile() {  
                    Duration = 60,  
                        Location = ResponseCacheLocation.None  
                });  
                options.CacheProfiles.Add("MyCache", new CacheProfile() {  
                    Duration = 60,  
                        Location = ResponseCacheLocation.Any  
                });  
            });  
            services.AddResponseCaching();  
        }  
    }  
}  

Homecontroller.cs

[ResponseCache(CacheProfileName = "MyCache")]  
[Route("home/LogData10")]  
public IActionResult LogData10() {  
    return View("LogData");  
}  

Output

Headers

Conclusion

Response Cache allows the client to cache the response to various cache controls. It helps us to reduce the number of requests a client or proxy makes to the Web Server.