I am trying to make an easy way to upload a file from FTP using FtpWebRequest using the WebRequestMethods.Ftp.DownloadFile method. The problem is that I will not show the progress of the download and therefore must know the file size ahead in order to be able to calculate the percentage percentage. But when I call GetResponse in FtpWebRequest , the ContentLength member is -1.
OK - that's why I pick up the file size in advance using the WebRequestMethods.Ftp.GetFileSize method. No problems. Then after getting the size, I upload the file.
This is where the problem arises ...
After getting the size, I try to reuse FtpWebRequest and resets the method to WebRequestMethods.Ftp.DownloadFile . This causes the System.InvalidOperationException say something like "This action cannot be completed after sending the request." (may not be the exact wording translated from the one I receive in Swedish).
I found elsewhere that while I set the KeepAlive property to true, it does not matter, the connection remains active. This is what I do not understand ... The only object I created is my FtpWebRequest object. And if I create another one, how can he know which connection to use? And what are the credentials?
Pseudocode:
Create FtpWebRequest Set Method property to GetFileSize Set KeepAlive property to true Set Credentials property to new NetworkCredential(...) Get FtpWebResponse from the request Read and store ContentLength
Now I got the file size. So it's time to upload the file. Knowing the configuration method raises the above exception. So am I creating a new FtpWebRequest ? Or is it anyway that the reset request is reused? (Closing the answer didn't make any difference.)
I do not understand how to move forward without re-creating the object. I could do it, but it's just not true. Therefore, I am posting here to find the right way to do this.
Here is the (non-working) code (inputs are sURI, sDiskName, sUser and sPwd.):
FtpWebRequest request = (FtpWebRequest)FtpWebRequest.Create(sURI); request.Method = WebRequestMethods.Ftp.GetFileSize; request.Credentials = new NetworkCredential(sUser, sPwd); request.UseBinary = true; request.UsePassive = true; request.KeepAlive = true; FtpWebResponse resp = (FtpWebResponse)request.GetResponse(); int contLen = (int)resp.ContentLength; resp.Close(); request.Method = WebRequestMethods.Ftp.DownloadFile; resp = (FtpWebResponse)request.GetResponse(); Stream inStr = resp.GetResponseStream(); byte[] buff = new byte[16384]; sDiskName = Environment.ExpandEnvironmentVariables(sDiskName); FileStream file = File.Create(sDiskName); int readBytesCount; int readTotal=0; while ((readBytesCount = inStr.Read(buff, 0, buff.Length)) > 0) { readTotal += readBytesCount; toolStripProgressBar1.Value = 100*readTotal/contLen; Application.DoEvents(); file.Write(buff, 0, readBytesCount); } file.Close();
Hope someone can explain how this should work. Thanks in advance.