29

I am developing against a proprietary library and I'm experiencing some issues with the cache of the HttpWebRequest. The library is using code equivalent to the one below to make the requests:

var request = WebRequest.Create("http://example.com/") as HttpWebRequest;

request.CachePolicy = new HttpRequestCachePolicy(HttpRequestCacheLevel.CacheIfAvailable);

The external resource doesn't disallow caching although each response differs. Thus I am ending up getting the same response each time.

Is there any way to clear the contents of the HttpWebRequest cache? The right solution would be to fix the external source or perhaps change the cache policy, but neither is possible - hence the question.

Clearing the cache could have various impacts, so preferably the solution would be to invalidate the cache on a per resource basis.

TheBoyan
  • 6,802
  • 3
  • 45
  • 61
Troels Thomsen
  • 11,361
  • 4
  • 28
  • 29
  • What was the answer to this? Bradley's answer is what I thought to be correct but empirically I have found clearing the IE cache (and using Fiddler) not to work. – Luke Puplett Jul 31 '12 at 17:39
  • I know this was asked some time ago, I thought this question [Clearing Page Cache in ASP.Net](http://stackoverflow.com/a/11641/128984) might be of some help as well. – Sir CodesALot Aug 09 '12 at 17:23

5 Answers5

15
public static WebResponse GetResponseNoCache(Uri uri)
{
        // Set a default policy level for the "http:" and "https" schemes.
        HttpRequestCachePolicy policy = new HttpRequestCachePolicy(HttpRequestCacheLevel.Default);
        HttpWebRequest.DefaultCachePolicy = policy;
        // Create the request.
        WebRequest request = WebRequest.Create(uri);
        // Define a cache policy for this request only. 
        HttpRequestCachePolicy noCachePolicy = new HttpRequestCachePolicy(HttpRequestCacheLevel.NoCacheNoStore);
        request.CachePolicy = noCachePolicy;
        WebResponse response = request.GetResponse();
        Console.WriteLine("IsFromCache? {0}", response.IsFromCache);            
        return response;
}

You can set the Cache Policy to the request to NoCacheNoStore to the HttpWebRequest.

AMing
  • 5,532
  • 2
  • 24
  • 15
  • 1
    As stated it isn't possible to change the cache policy. I would like a solution for actually clearing the cache store - not avoiding caching entirely. – Troels Thomsen Mar 12 '09 at 09:03
  • I believe that CyberMing is correct. NoCacheNoStore will actually clear the cache store for the requested url, and may actually be what you're looking for? >(from documentation) HttpRequestCacheLevel.NoCacheNoStore ... Never satisfies a request by using resources from the cache and does not cache resource. **If the resource is present in the local cache, it is removed**... – snowcode Dec 07 '11 at 18:25
  • I was searching how to know where does the response come from (from cache or not because Status is always 200 as if no cache where used) and you give me the response: IsFromcache. Thanks. – MuiBienCarlota Dec 03 '12 at 16:24
  • 1
    Why did you add the first two lines (with the ` HttpWebRequest.DefaultCachePolicy = policy;`)? Wouldn't it work just the same even without them? – BornToCode Feb 27 '17 at 21:17
  • 1
    @MuiBienCarlota response.IsFromCache – Ark-kun Aug 13 '17 at 11:24
13

HttpWebRequest uses System.Net.Cache.RequestCache for caching. This is an abstract class; the actual implementation in the Microsoft CLR is Microsoft.Win32.WinInetCache which, as the name implies, uses the WinInet functions for caching.

This is the same cache used by Internet Explorer, so you can manually clear the cache by using IE's Delete Browsing History dialog. (Do this first as a test, to make sure clearing the WinInet cache solves your problem.)

Assuming that clearing the WinInet cache solves the problem, you can delete files programmatically by P/Invoking to the DeleteUrlCacheEntry WinInet API:

public static class NativeMethods
{
    [DllImport("WinInet.dll", PreserveSig = true, SetLastError = true)]
    public static extern void DeleteUrlCacheEntry(string url);
}
Steve Dunn
  • 21,044
  • 11
  • 62
  • 87
Bradley Grainger
  • 27,458
  • 4
  • 91
  • 108
  • You've right, Microsoft.Win32.WinInetCache is involved and response is read from Microsoft.Win32.WinInetCache.ReadStream but it doesn't means it's same cache location than IE. – MuiBienCarlota Dec 03 '12 at 16:19
  • 3
    @MuiBienCarlota: In practice, I've found that it is. As far as I know, Internet Explorer still uses the WinInet cache functions; if both it and .NET are running under the same user account, the files created/deleted by `CreateUrlCacheEntry` and `DeleteUrlCacheEntry` should be in the same place. – Bradley Grainger Dec 03 '12 at 19:34
  • Helpful answer, but do you know if HttpWebRequest caches responses when running on Linux (.NET Core / .Net Standard), and if so, where? – Joe Apr 10 '19 at 18:08
  • @Joe that's sufficiently different that you should ask a new question. – Bradley Grainger Apr 10 '19 at 19:05
  • @BradleyGrainger - yes I might do that after I've done a bit of research, thanks. – Joe Apr 10 '19 at 20:37
1

I haven't tried, but a solution could be to add an arbitrary query string to the url being requested.

This querystring would change everytime, maybe using DateTime.Now meaning the url would be different each time. Each request would then get requested supposedly anew.

jussinen
  • 688
  • 5
  • 16
0

You can change the cache policy: use an http reverse proxy, and remove/change the relevant http headers. It's a hack, but it would work, and quite easily. I'd suggest you use Apache httpd server for this task (with mod_proxy).

Ron Klein
  • 9,178
  • 9
  • 55
  • 88
-1

Add the following line to clear the cache as and when the Webclient fetches the data:

Webclient.Headers.Add(HttpRequestHeader.CacheControl, "no-cache")
robinCTS
  • 5,746
  • 14
  • 30
  • 37