chemitaxis
chemitaxis

Reputation: 14889

Web API 2.0 IHttpActionResult cache

I'm using this code to return an object content, but I would like to cache the response adding the Cache-Control headers.

[AllowAnonymous]
[Route("GetPublicContent")]
[HttpGet]
 public IHttpActionResult GetPublicContent([FromUri]UpdateContentDto dto)
        {

            if (dto == null)
                return BadRequest();

            var content = _contentService.GetPublicContent(dto);
            if (content == null)
                return BadRequest();
            return new Ok(content);

        }

Just that! Thanks!!

Upvotes: 2

Views: 2112

Answers (2)

Paul Oliver
Paul Oliver

Reputation: 7671

Make a new class that inherits from OkNegotiatedContentResult<T>:

public class CachedOkResult<T> : OkNegotiatedContentResult<T>
{
    public CachedOkResult(T content, TimeSpan howLong, ApiController controller) : base(content, controller)
    {
        HowLong = howLong;
    }

    public CachedOkResult(T content, IContentNegotiator contentNegotiator, HttpRequestMessage request, IEnumerable<MediaTypeFormatter> formatters) 
    : base(content, contentNegotiator, request, formatters) { }

    public TimeSpan HowLong { get; private set; }


    public override async Task<HttpResponseMessage> ExecuteAsync(CancellationToken cancellationToken)
    {
        var response = await base.ExecuteAsync(cancellationToken);
        response.Headers.CacheControl = new CacheControlHeaderValue() {
            Public = false,
            MaxAge = HowLong
        };

        return response;
    }
}

To use this in your controller, just return a new instance of the CachedOkResult class:

public async Task<IHttpActionResult> GetSomething(string id)
{
    var value = await GetAsyncResult(id);
    // cache result for 60 seconds
    return new CachedOkResult<string>(value, TimeSpan.FromSeconds(60), this);
}

The headers will come across the wire like this:

Cache-Control:max-age=60
Content-Length:551
Content-Type:application/json; charset=utf-8
... other headers snipped ...

Upvotes: 1

matt_lethargic
matt_lethargic

Reputation: 2786

You can set it 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;
}

Update

Or try this question

Upvotes: 0

Related Questions