views:

301

answers:

6

Good day.

I'm using the WebClient class in my C# application in order to download the same file every minute, and then the application performs a simple check to see if the file has been changed, and if it does do something with it.

Well since this file is downloaded every minute the WebClient caching system is caching the file, and not downloading the file again, just simply getting it from the cache, and that gets in the way of checking if the file downloaded is new.

So i would like to know how can disable the caching system of the WebClient class.

I've tried.

Client.CachePolicy = new System.Net.Cache.RequestCachePolicy(System.Net.Cache.RequestCacheLevel.BypassCache);

I also tried headers.

WebClient.Headers.Add("Cache-Control", "no-cache");

Didn't work as well. So how can i disable the cache for good?

Thanks.

EDIT

I also tried the following CacheLevels: NoCacheNoStore, BypassCache, Reload. No effect, however if i reboot my computer the cache seems to be cleared, but i can't be rebooting the computer every time.

A: 

Try NoCacheNoStore:

Never satisfies a request by using resources from the cache and does not cache resources. If the resource is present in the local cache, it is removed. This policy level indicates to intermediate caches that they should remove the resource. In the HTTP caching protocol, this is achieved using the no-cache cache control directive.

client.CachePolicy = new System.Net.Cache.RequestCachePolicy(System.Net.Cache.RequestCacheLevel.NoCacheNoStore); 
KMan
@KMan: Also tried that. No cache level had any affect.
Fábio Antunes
@Fabio may be you will have to use Webrequest for this
Aamod Thakur
BranchCache service (Windows 7) may be still conflicting - turn it off, test.
mhambra
@mhambra: The BranchService is a caching service for local network based resources, nothing to do with Web resources, however its off and still doesn't work.
Fábio Antunes
@Fábio Antunes: Can you share with us your exact code, possible the whole method the way you are calling the methods?
KMan
+1  A: 

I Guess you will have to use webrequest/webresponse rather than webclient

    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();

//below is the function for downloading the file

   public static int DownloadFile(String remoteFilename,
                           String localFilename)
    {
        // Function will return the number of bytes processed
        // to the caller. Initialize to 0 here.
        int bytesProcessed = 0;

        // Assign values to these objects here so that they can
        // be referenced in the finally block
        Stream remoteStream = null;
        Stream localStream = null;
        WebResponse response = null;

        // Use a try/catch/finally block as both the WebRequest and Stream
        // classes throw exceptions upon error
        try
        {
            // Create a request for the specified remote file name
            WebRequest request = WebRequest.Create(remoteFilename);
            // Define a cache policy for this request only. 
            HttpRequestCachePolicy noCachePolicy = new HttpRequestCachePolicy(HttpRequestCacheLevel.NoCacheNoStore);
            request.CachePolicy = noCachePolicy;
            if (request != null)
            {
                // Send the request to the server and retrieve the
                // WebResponse object 
                response = request.GetResponse();

                if (response != null)
                {
                    if (response.IsFromCache)
                        //do what you want

                    // Once the WebResponse object has been retrieved,
                    // get the stream object associated with the response's data
                    remoteStream = response.GetResponseStream();

                    // Create the local file
                    localStream = File.Create(localFilename);

                    // Allocate a 1k buffer
                    byte[] buffer = new byte[1024];
                    int bytesRead;

                    // Simple do/while loop to read from stream until
                    // no bytes are returned
                    do
                    {
                        // Read data (up to 1k) from the stream
                        bytesRead = remoteStream.Read(buffer, 0, buffer.Length);

                        // Write the data to the local file
                        localStream.Write(buffer, 0, bytesRead);

                        // Increment total bytes processed
                        bytesProcessed += bytesRead;
                    } while (bytesRead > 0);
                }
            }
        }
        catch (Exception e)
        {
            Console.WriteLine(e.Message);
        }
        finally
        {
            // Close the response and streams objects here 
            // to make sure they're closed even if an exception
            // is thrown at some point
            if (response != null) response.Close();
            if (remoteStream != null) remoteStream.Close();
            if (localStream != null) localStream.Close();
        }

        // Return total bytes processed to caller.
        return bytesProcessed;
    }
Aamod Thakur
@Aamod Thakur: Yes. I've tried such method, however i could save the response to file. Which was the purpose in the first place.
Fábio Antunes
@Aamod Thakur: Have you ever downloaded a file using the WebRequest class?. How exactly do you save the file?
Fábio Antunes
@Fabio see the edit. use the function and see if it helps u
Aamod Thakur
@Aamod: Have you tried the code? Before i posted this question I've tried this method and didn't worked.. NullReferenceException at bytesRead = remoteStream.Read(buffer, 0, buffer.Length). And i also tried replacing for "int bytesRead = 0;" Same problem.
Fábio Antunes
@Aamod: I've successfully fixed the code to save the request as a stream, however `WebRequest` is still using the cache to load the file.
Fábio Antunes
+1  A: 
client.CachePolicy = new RequestCachePolicy(RequestCacheLevel.BypassCache);

Should work. Just make sure you clear the cache and delete any temporary downloaded files in Internet Explorer before running the code as System.Net and IE both use the same cache.

Darin Dimitrov
@Darin: Still doesn't work. I've tried every `CacheLevel` that it would disable caching of the file and nothing, and cleaning the IE Temps didn't had any effect as well.
Fábio Antunes
+3  A: 

In some scenarios, network debugging software can cause this issue. To make sure your url is not cached, you can append a random number as last parameter to make url unique. This random parameter in most cases is ignored by servers (which try to read parameters sent as name value pairs).

Example: http://www.someserver.com/?param1=val1&ThisIsRandom=RandomValue

Where ThisIsRandom=RandomValue is the new parameter added.

ivymike
@ivymike: I know what you mean, and that would work if i was trying do download a webpage. In this case is a file, with a url something like: www.example.com/files/now.zip
Fábio Antunes
This should still work -- even with request types other than html. The url would look like www.example.com/files/now.zip?rand=randomvalue
Dan Esparza
Like Dan was saying, it should work for all types of requests.
ivymike
@Dan Esparza, Ivymike: You're right it worked. Never tough using the parameter at the end of the file url. Thanks.
Fábio Antunes
@Dan Esparza, Ivymike: I regret to say that not even with a random value in a parameter at the end of the file url as worked.
Fábio Antunes
+1  A: 

You could try appending some random number to your url as part of a querystring each time you download the file. This ensures that urls are unique each time.

For ex-

Random random = new Random();
string url = originalUrl + "?random=" + random.Next().ToString();
webclient.DownloadFile(url, downloadedfileurl);
Vinay B R
@Vinary: I regret to say that not even with a random value in a parameter at the end of the file url as worked at downloading the file not using the cached version of the file.
Fábio Antunes
+1  A: 

From the above I would guess that you have problem somewhere else. Can you log http requests on server side? What do you get when you alter some random seed parameter?

Maybe SERVER caches the file (if the log shows that request is really triggered every minute.

Do you use ISA or SQUID?

What is http response code for your request?

I know that answering with answers might not be popular, but comment doesn't allow me this much text :)

EDIT:

Anyway, use HttpRequest object instead of WebClient, and hopefully (if you place your doubts in WebClient) everything will be solved. If it wasn't solved with HttpRequest, then the problem really IS somewhere else.

Further refinement:

Go even lower: http://stackoverflow.com/questions/2109695/how-do-i-create-an-http-request-manually-in-net

This is pure sockets, and if the problem still persists, then open a new question and tag it WTF :)

Daniel Mošmondor
@Daniel: About the server i don't know nothing once its not mine, and don't I control it. However the file is being cached by `System.Net` and IE, and not when using Firefox, i know that because sometimes i interrupt the zip download in my App resulting in a corrupted downloaded zip, and sometimes such corrupted zip stays in cache, and every time my App or IE downloads the file again, he downloads the corrupted version from the cache. But if i download the file using Firefox he downloads the zip file in perfect condition.
Fábio Antunes
OK, but what for other ideas? Do you have proxy server of some kind that is involved?
Daniel Mošmondor
@Daniel: No proxy is in use. I also tried clearing the cache through IE, and manually didn't work. I already tried downloading the file using a `WebClient` and also tried with `WebRequest` and then save the ResponseStream into a file, same problem they all use cache even using the Random parameter technique, and stating the `CachePolicy` property of each one not to use the Cache. And the `Cache-Control` header didn't work as well.
Fábio Antunes
@Daniel: I doubt it will work, once HttpWebResquest and the other classes I've used share the same backbone class. Basically they're pretty much the same.
Fábio Antunes
I am not sure about this, but not sure that it isn't so either. Well, try this then: http://stackoverflow.com/questions/2109695/how-do-i-create-an-http-request-manually-in-net
Daniel Mošmondor
@Daniel. A socket request! I have a felling this might work, you should post it on your answer wile i try it. So that people with the same problem find the answer easily.
Fábio Antunes