Implementing .NET Core API Caching in C#
By FoxLearn 1/10/2025 2:34:59 AM 62
Caching an API response can significantly improve the performance of your API by avoiding the need to regenerate the response each time. Instead, the response is retrieved from memory, making it especially beneficial for API endpoints with expensive or time-consuming computations that return the same results repeatedly.
Enable Caching in Program.cs
First, ensure that caching is enabled globally in your application by adding AddResponseCaching
and UseResponseCaching
in your Program.cs
file:
var builder = WebApplication.CreateBuilder(args); // Add services to the container. builder.Services.AddControllers(); builder.Services.AddResponseCaching(); // Add response caching service var app = builder.Build(); // Configure the HTTP request pipeline. app.UseHttpsRedirection(); // UseResponseCaching should be called after any other middleware such as UseCors app.UseResponseCaching(); // Enable response caching middleware app.UseAuthorization(); app.MapControllers(); app.Run();
Make sure UseResponseCaching
is called after UseCors
(if CORS is enabled).
In the code above:
AddResponseCaching()
registers the necessary services to support response caching.UseResponseCaching()
middleware is added to the request pipeline.
Use the [ResponseCache] Attribute in Controllers
Next, you need to specify caching behavior for each API endpoint using the [ResponseCache]
attribute.
The [ResponseCache]
attribute allows you to control the caching parameters for an individual action. You can specify the duration for which the response should be cached and configure other settings like how the cache should vary based on query parameters or headers.
using Microsoft.AspNetCore.Mvc; namespace MyApi.Controllers { [Route("api/[controller]")] [ApiController] public class CatFactsController : ControllerBase { [HttpGet] [ResponseCache(Duration = 10)] // Cache the response for 10 seconds public string GetCatFact() { // Simulate fetching a random cat fact var catFact = "Cats have five toes on their front paws, but only four toes on their back paws."; return catFact; } } }
In the example above, the GetCatFact
action is cached for 10 seconds. When the same request is made within that time, the response will be fetched from the cache rather than executing the logic again.
Vary Cache Based on Query Parameters or Headers
You can vary the cache based on query parameters or headers using VaryByQueryKeys
or VaryByHeader
.
[HttpGet] [ResponseCache(Duration = 30, VaryByQueryKeys = new[] { "id", "search" })] // Cache based on query parameters public string GetCatFact([FromQuery] int id, [FromQuery] string search) { // Simulate fetching a random cat fact, with a variation based on 'id' and 'search' query parameters var catFact = $"Cat Fact for {id} with search term '{search}'"; return catFact; }
In this example, the cache is varied by the id
and search
query parameters, meaning different combinations of these parameters will result in different cached responses.
Define Cache Profiles for Reusability
Instead of specifying caching settings directly on each controller action, you can define cache profiles in Program.cs
or Startup.cs
and apply them globally or to specific actions.
For example, you can define a cache profile for default caching behavior:
builder.Services.AddControllers(options => { options.CacheProfiles.Add("Default", new CacheProfile() { Duration = 10 }); options.CacheProfiles.Add("Client", new CacheProfile() { Location = ResponseCacheLocation.Client, Duration = 10 }); });
Then, use the CacheProfileName
property of the [ResponseCache]
attribute:
[HttpGet] [ResponseCache(CacheProfileName = "DefaultCache")] public string GetCatFact() { var catFact = "Cats love to sleep for 12-16 hours a day."; return catFact; } [HttpGet("2")] [ResponseCache(CacheProfileName = "Client", VaryByQueryKeys = new[] { "id", "search" })] // Use the "Client" profile with query parameter variation public string? GetCatFact2([FromQuery] int id, [FromQuery] string search) { CatModel? catFact = _httpRepository.GetAsync<CatModel>("https://catfact.ninja/fact").Result; return catFact?.Fact + id + search; }
By implementing response caching, you can speed up your API by storing frequently accessed data in memory, reducing the need to reprocess the same requests. You can fine-tune caching based on query parameters, headers, or reusable cache profiles for optimal performance.
- Content Negotiation in Web API
- How to fix 'InvalidOperationException: Scheme already exists: Bearer'
- How to fix System.InvalidOperationException: Scheme already exists: Identity.Application
- Add Thread ID to the Log File using Serilog
- Handling Exceptions in .NET Core API with Middleware
- InProcess Hosting in ASP.NET Core
- Limits on ThreadPool.SetMinThreads and SetMaxThreads
- Controlling DateTime Format in JSON Output with JsonSerializerOptions