When is C# Web API response caching turned on by default in .NET Core projects?

Viewed 44

My understanding of the C# attribute [ResponseCache] (I think) it uses the request and request headers as a key, then caches the response in memory. This obviously makes sense for static content like images, css etc. This clearly does not make sense for API requests which are never static and always changing.

Here is a link to what Microsoft say C# Web API response caching is https://docs.microsoft.com/en-us/aspnet/core/performance/caching/response?view=aspnetcore-6.0

From the documentation I can see that I can disable web caching for something that does not make sense to cache via the following:

[ResponseCache(NoStore = true, Location = ResponseCacheLocation.None)]
[HttpGet(api/GetRandomNumber/{seed}}

I see that you can also explicitly add it to middleware to enable it via the following example:

app.UseResponseCaching();

app.Use(async (context, next) =>
{
    context.Response.GetTypedHeaders().CacheControl =
        new Microsoft.Net.Http.Headers.CacheControlHeaderValue()
        {
            Public = true,
            MaxAge = TimeSpan.FromSeconds(10)
        };
    context.Response.Headers[Microsoft.Net.Http.Headers.HeaderNames.Vary] =
        new string[] { "Accept-Encoding" };

    await next();
});

Our benchmarking showed that without our knowledge (or any code to enable it), it appears that response caching was enabled by default. Memory usage dropped by half when we added the attribute to our authenticated API call.

[ResponseCache(NoStore = true, Location = ResponseCacheLocation.None)]

The question is. Under what circumstances is response caching turned on by default? If we didn't add add ResponseCache attributes to anything, and we didn't call app.UseResponseCaching() - how is it possible that response caching was enabled?

1 Answers

You can use the below line of code in API Controller class which works for me

[ResponseCache(Location = ResponseCacheLocation.None, Duration = 0, NoStore = true)]

Also, for MVC based application, you can use the below line of code -

builder.Services.AddControllersWithViews().AddMvcOptions(options => 
    options.Filters.Add(
        new ResponseCacheAttribute
        {
            NoStore = true, 
            Location = ResponseCacheLocation.None,
            Duration = 0
        }));

Related