简体   繁体   中英

DelegatingHandler to cache an HttpResponseMessage

I'm trying to cache a response to a webapi endpoint requests.

I've created a DelegatingHadler that short circuits the pipeline reusing a previously generated response, and it does not work.

What am I doing wrong? or how can I do it correctly?

This is my DH:

public class StuffCache : DelegatingHandler
{
    public const string URL_CACHED = @"/stuff-endpoint/items";

    ObjectCache cache = MemoryCache.Default;

    public StuffCache()
    {
        cache = MemoryCache.Default;
    }

    protected async override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
    {

        if (request.Method == HttpMethod.Get)
        {
            if (request.RequestUri.AbsolutePath.ToLower() == URL_CACHED)
            {
                HttpResponseMessage response = (HttpResponseMessage)cache["CachedItemName"];

                if (response == null)
                {
                    response = await base.SendAsync(request, cancellationToken);
                    cache.Add("CachedItemName", response, null);
                }

                return response;
            }
        }

        return await base.SendAsync(request, cancellationToken);
    }

}

Cimpress.Extensions.Http.Caching.InMemory is a NuGet package that offers various HTTP related utility methods, notably an HttpMessageHandler that caches the results of an HTTP GET request.

The code for the DelegatingHandler can be found on GitHub .

One of the points to consider is to cache the HttpResonseMessage.Content result separately since a stream, especially a network stream, is meant to be only read once.

Caching the same entire response object isn't advisable as it's tied to the request lifecycle so you would be caching a lot more than you bargained for. You could cache the content and some other metadata (statuscode, headers, etc). On cache hit use request.GetResponse(...) then set content and values you need.

Off the top of my head steps

  1. Check cache
  2. If in cache create response from request
  3. If not in cache hit api, get data, cache content and metadata for subsequent calls making sure to set expiree to avoid stale data

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM