Caching in ASP.NET

Caching– is one of the most popular and effective approaches used in software development. Its essence is to reuse already obtained results of long or heavy operations, avoiding their repeated execution. After a complex task is completed, the result is stored in a cache and retrieved from there when it is requested again, instead of having to perform the same operation again. This approach is designed to make it much easier on the server and speed up the application.

 

In-Memory Caching

The Microsoft.Extensions.Caching.Memory library from the Nuget repository must be plugged into the project

First you need to register the service in the ServiceCollection in Startup.cs

services.AddMemoryCache();

Then use the cache management object in the service or controller

public class WeatherService
{
    private readonly IMemoryCache _memoryCache;
    private readonly string _cacheKey = "WeatherData";

    public WeatherService(IMemoryCache memoryCache)
    {
        _memoryCache = memoryCache;
    }

    public WeatherForecast GetWeather()
    {
        if (!_memoryCache.TryGetValue(_cacheKey, out WeatherForecast forecast))
        {
            // Имитация получения данных
            forecast = FetchWeatherFromApi();

            // Установка кэша с временем жизни
            var cacheOptions = new MemoryCacheEntryOptions
            {
                AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(5),
                SlidingExpiration = TimeSpan.FromMinutes(2)
            };

            _memoryCache.Set(_cacheKey, forecast, cacheOptions);
        }

        return forecast;
    }
}

Distributed Caching

Distributed caching allows you to store data in a centralized repository accessible to multiple servers. If one server stores a cache item, other servers can use it as well. There are popular database implementations such as Redis and SQL Server, as well as specialized ones such as NCache.

Let's consider the popular Redis database implementation.

The Microsoft.Extensions.Caching.StackExchangeRedis library from Nuget is used for this type of caching

Register Redis in Startup.cs

services.AddStackExchangeRedisCache(options =>
{
    options.Configuration = "localhost:6379";
    options.InstanceName = "RedisCache";
});

Further, the usage is similar to that of In-Memory Cache

public async Task<string> GetProductAsync(int productId)
    {
        string cacheKey = $"Product_{productId}";
        string product = await _distributedCache.GetStringAsync(cacheKey);

        if (string.IsNullOrEmpty(product))
        {
            // Имитация получения данных
            product = FetchProductFromDb(productId);

            // Установка кэша
            var options = new DistributedCacheEntryOptions
            {
                AbsoluteExpirationRelativeToNow = TimeSpan.FromHours(1)
            };

            await _distributedCache.SetStringAsync(cacheKey, product, options);
        }

        return product;
    }

Important: You should disable caching for content that contains information for authorized clients. Caching should only be enabled for data that does not change depending on the identity of the user or whether the user is logged in. Caching is best used for data that rarely or never changes. However, for data that is frequently updated, such as the current time, caching is not appropriate because it can lead to outdated or incorrect results.

Response Caching

Response Caching is a simple and effective way to improve the performance of ASP.NET applications, especially for repetitive requests with unchanging content. It is used to cache HTTP responses to improve application performance and reduce server load. This method allows you to reuse previously generated responses to identical requests, minimizing the cost of processing such requests.

Enable Middleware in Program.cs or Startup.cs

app.UseResponseCaching();

Further, you can use method attributes to enable output caching for a particular controller method

[HttpGet]
[ResponseCache(Duration = 60, Location = ResponseCacheLocation.Client, NoStore = false)]
public IActionResult GetWeather()
{
    var weatherData = FetchWeatherFromApi();
    return Ok(weatherData);
}

This solution adds caching headers (Cache-Control, Expires, etc.). These headers inform clients (browsers, proxy servers) about the possibility of caching the response on their side.

OutputCache (ASP.NET Core 7.0 and higher)

Starting with ASP.NET Core 7.0 version, the framework has a more modern approach for server-side caching.

It stores the generated response on the server side and returns it for an identical request, which significantly reduces the load on the server, since the request processing is not repeated.

In addition, this method allows you to customize the response based on requests, headers, or parameters.

It is customized by simply adding the OutputCache attribute to the controller method.

[HttpGet]
[OutputCache(Duration = 60, VaryByQueryKeys = new[] { "category" })]
public IActionResult GetProducts(string category)
{
    var products = FetchProductsByCategory(category);
    return Ok(products);
}

Key differences between ResponseCache and OutputCache

Parameter ResponseCache OutputCache
Output Cache Location Client-side and proxy-side. Server side.
Purpose Manage HTTP headers for cache. Caching generated responses.
Flexibility Limited to HTTP headers. Supports filtering by query, headers, and parameters.
Performance Reduces the number of requests to the server. Reduces the load on the server and processing.
Version of ASP.NET Only ASP.NET Core. ASP.NET Core 7.0 and higher.

 

  • Use ResponseCache if you need to manage client and proxy caching via HTTP headers (e.g., for browsers).
  • Use OutputCache if you need server-side caching to reduce load and speed up responses to identical requests.