Setting HTTP cache control headers in Web API

C#asp.net Web-ApiHttp Caching

C# Problem Overview


What's the best way to set cache control headers for public caching servers in WebAPI?

I'm not interested in OutputCache control on my server, I'm looking to control caching at the CDN side and beyond (I have individual API calls where the response can be indefinitely cached for the given URL) but everything I've read thus far either references pre-release versions of WebAPI (and thus references things that seem to no longer exist, like System.Web.HttpContext.Current.Reponse.Headers.CacheControl) or seems massively complicated for just setting a couple of http headers.

Is there a simple way to do this?

C# Solutions


Solution 1 - C#

As suggested in the comments, you can create an ActionFilterAttribute. Here's a simple one that only handles the MaxAge property:

public class CacheControlAttribute : System.Web.Http.Filters.ActionFilterAttribute
{
    public int MaxAge { get; set; }

    public CacheControlAttribute()
    {
        MaxAge = 3600;
    }

    public override void OnActionExecuted(HttpActionExecutedContext context)
    {
        if (context.Response != null)
            context.Response.Headers.CacheControl = new CacheControlHeaderValue()
            {
                Public = true,
                MaxAge = TimeSpan.FromSeconds(MaxAge)
            };

        base.OnActionExecuted(context);
    }
}

Then you can apply it to your methods:

 [CacheControl(MaxAge = 60)]
 public string GetFoo(int id)
 {
    // ...
 }

Solution 2 - C#

The cache control header can be set like this.

public HttpResponseMessage GetFoo(int id)
{
    var foo = _FooRepository.GetFoo(id);
    var response = Request.CreateResponse(HttpStatusCode.OK, foo);
    response.Headers.CacheControl = new CacheControlHeaderValue()
        {
            Public = true,
            MaxAge = new TimeSpan(1, 0, 0, 0)
        };
    return response;
}

Solution 3 - C#

In case anyone lands here looking for an answer specifically to ASP.NET Core, you can now do what @Jacob suggested without writing your own filter. Core already includes this:

[ResponseCache(VaryByHeader = "User-Agent", Duration = 1800)]
public async Task<JsonResult> GetData()
{
}

https://docs.microsoft.com/en-us/aspnet/core/performance/caching/response

Solution 4 - C#

Like this answer suggesting filters, consider the "extended" version -- http://www.strathweb.com/2012/05/output-caching-in-asp-net-web-api/

It used to be available as a NuGet package Strathweb.CacheOutput.WebApi2, but doesn't seem to be hosted anymore, and is instead on GitHub -- https://github.com/filipw/AspNetWebApi-OutputCache

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questionuser32826View Question on Stackoverflow
Solution 1 - C#JacobView Answer on Stackoverflow
Solution 2 - C#Darrel MillerView Answer on Stackoverflow
Solution 3 - C#mattferdererView Answer on Stackoverflow
Solution 4 - C#drzausView Answer on Stackoverflow