Come cancellare la cache di HttpWebRequest

Sto sviluppando contro una libreria proprietaria e sto riscontrando alcuni problemi con la cache di HttpWebRequest . La libreria utilizza un codice equivalente a quello sottostante per effettuare le richieste:

 var request = WebRequest.Create("http://example.com/") as HttpWebRequest; request.CachePolicy = new HttpRequestCachePolicy(HttpRequestCacheLevel.CacheIfAvailable); 

La risorsa esterna non impedisce la memorizzazione nella cache, sebbene ogni risposta differisca. Così finisco sempre per ottenere la stessa risposta ogni volta.

C’è un modo per cancellare il contenuto della cache HttpWebRequest ? La soluzione giusta sarebbe quella di correggere l’origine esterna o forse modificare la politica della cache, ma nessuno dei due è ansible – da qui la domanda.

Cancellare la cache potrebbe avere vari impatti, quindi preferibilmente la soluzione sarebbe invalidare la cache per risorsa.

 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; } 

È ansible impostare la politica della cache per la richiesta su NoCacheNoStore su HttpWebRequest.

HttpWebRequest utilizza System.Net.Cache.RequestCache per la memorizzazione nella cache. Questa è una class astratta; l’implementazione effettiva in Microsoft CLR è Microsoft.Win32.WinInetCache che, come suggerisce il nome, utilizza le funzioni WinInet per la memorizzazione nella cache.

Questa è la stessa cache utilizzata da Internet Explorer, quindi puoi cancellare manualmente la cache utilizzando la finestra di dialogo Elimina cronologia esplorazioni di IE. (Fatelo prima come test, per assicurarvi che la cancellazione della cache WinInet risolva il problema.)

Supponendo che la cancellazione della cache WinInet risolva il problema, è ansible eliminare i file a livello di programmazione mediante P / Invocazione all’API WinInet DeleteUrlCacheEntry :

 public static class NativeMethods { [DllImport("WinInet.dll", PreserveSig = true, SetLastError = true)] public static extern void DeleteUrlCacheEntry(string url); } 

Non ho provato, ma una soluzione potrebbe essere quella di aggiungere una stringa di query arbitraria alla URL richiesta.

Questa querystring cambierebbe ogni volta, magari usando DateTime.Ora che significa che l’url sarebbe diverso ogni volta. Ogni richiesta verrà quindi richiesta presumibilmente di nuovo.

È ansible modificare la politica della cache: utilizzare un proxy inverso http e rimuovere / modificare le intestazioni http pertinenti. È un hack, ma funzionerebbe, e abbastanza facilmente. Ti suggerirei di utilizzare il server httpd di Apache per questa attività (con mod_proxy).

Aggiungere la seguente riga per svuotare la cache man mano che il Webclient recupera i dati:

 Webclient.Headers.Add(HttpRequestHeader.CacheControl, "no-cache")