I have some code running within an ApiController (ASP.Net Web API) that itself wants to make a GET request to another web service. The web service (also part of my app) returns Cache-Control headers indicating an expiry time for the content it returns.
I am using the new System.Net.Http.HttpClient
, configured with a WebRequestHandler
in order to use client-side caching (the default HttpClientHandler
does not support cache configuration, although it does use System.Net.WebRequest
as its underlying HTTP implementation):
var client = new HttpClient(new WebRequestHandler {
UseDefaultCredentials = true,
CachePolicy = new RequestCachePolicy(RequestCacheLevel.Default)
});
var response = client.GetAsync("someUri").Result;
response.EnsureSuccessStatusCode();
On the server I am enabling caching within my controller action via...
var response = new HttpResponseMessage(HttpStatusCode.OK);
response.Headers.CacheControl = new CacheControlHeaderValue {
Public = true,
MaxAge = new TimeSpan(0, 5, 0); // Five minutes in this case
};
// Omitted, some content is added to the response
return response;
The above (abbreviated) code works correctly within a test; I make multiple calls to the service in this way and only the first call actually contacts the service (observed via log messages on the service in IIS); subsequent calls use the cache.
However, running the same code hosted on IIS itself, it seems the HttpClient
ignores the caching result (I have also set up my IoC container such that only one instance of the HttpClient
exists in the AppDomain) and calls the service each time. This is running as the AppPoolIdentity.
Interestingly, if I change the app pool to run as NetworkService, then the response has status code 401 Unauthorized (I have tried setting Preauthenticate = true
on the WebRequestHandler
but the status code is still 401). The same is true if I change the app pool to run under my own credentials.
So, is there something about running the App Pool under the NetworkService identity, and virtual AppPoolIdentity, that prevents them from using client-side caching. Where does the content cached by WebRequest
physically exist anyway?
To enable caching, Duration must be set to a positive value and Location must be either Any (the default) or Client . The framework sets the Cache-Control header to the location value followed by the max-age of the response.
Response Caching is an ideal technique for speeding up a wide variety of web applications. Frequently used pages are cached and therefore served faster than the normal approach of generating the web page each and every time the user visits the page.
Caching makes a copy of data that can be returned much faster than from the source. Apps should be written and tested to never depend on cached data. ASP.NET Core supports several different caches. The simplest cache is based on the IMemoryCache. IMemoryCache represents a cache stored in the memory of the web server.
WinInet caching is not supported when running on IIS, please check the following support article from MS http://support.microsoft.com/kb/238425
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With