0

Trying to create an ftp download async function with IProgress and cancelation token, but I'm getting a "ProtocolViolationException: Operation is not valid due to the current state of the object" on GetRequestStreamAsync() function

I was using this as an inspiration upload async with IProgress and cancelation token

        public async Task DownloadWithProgressAsync(string remoteFilepath, string localFilepath, IProgress<decimal> progress, CancellationToken token)
        {
            const int bufferSize = 128 * 1024;  // 128kb buffer
            progress.Report(0m);

            var remoteUri = new Uri(_baseUrl + remoteFilepath);
            Debug.Log($"Download\nuri: {remoteUri}");

            var request = (FtpWebRequest)WebRequest.CreateDefault(remoteUri);
            request.Method = WebRequestMethods.Ftp.DownloadFile;
            request.Credentials = new NetworkCredential(_username, _password);

            token.ThrowIfCancellationRequested();

            using (var fileStream = new FileStream(localFilepath, FileMode.OpenOrCreate, FileAccess.Write,
                FileShare.Write, bufferSize, true))
            {
                using (var ftpStream = await request.GetRequestStreamAsync())
                {
                    var buffer = new byte[bufferSize];
                    int read;
                    while ((read = await ftpStream.ReadAsync(buffer, 0, buffer.Length, token) ) > 0)
                    {
                        await fileStream.WriteAsync(buffer, 0, read, token);
                        var percent = (decimal)ftpStream.Position / ftpStream.Length;
                        progress.Report(percent);
                    }
                }
            }

            var response = (FtpWebResponse)await request.GetResponseAsync();
            var success = (int)response.StatusCode >= 200 && (int)response.StatusCode < 300;
            response.Close();
            if (!success)
                throw new Exception(response.StatusDescription);
        }
  • Can you try `(FtpWebRequest)WebRequest.Create(remoteUri)` instead of your code? Also, can you show your `remoteUri`? – cassandrad May 25 '20 at 13:17
  • I had (FtpWebRequest)WebRequest.Create(remoteUri) before, my remoteUri is ftp://94.10.187.166/AS4238_Apprentices_Mate/Audio/2a7ab534-cd9a-405c-bc8a-aab87efcf4fd.mp3 – Carlos Frias May 25 '20 at 13:23
  • Can you add the scheme to your address? So it would be like `ftp://94.10.xx.xx`. – cassandrad May 25 '20 at 13:29
  • Yes it is ```ftp://94.10.187.166/...``` but on my last message it created the link – Carlos Frias May 25 '20 at 13:34
  • It is strange that you are obtaining request stream and is trying to read something from it. Normally you would want to write something there. Can you try to call `GetResponse` instead of `GetRequestStreamAsync` and read from response's stream? It could be that it is not allowed to get request stream if you set `DownloadFile` method. – cassandrad May 25 '20 at 13:45
  • I've tried that. Dont get the ProtocolViolationException but it doesn't download the file, I end up with a file with 0 bytes. – Carlos Frias May 25 '20 at 13:51
  • Maybe it will be a better solution to post the code with `GetResponse` as a new question and ask why it does not download the file. At least it can be profiled. By the way, did you look at packets FTP server sends? Maybe there is some error on that side? – cassandrad May 25 '20 at 14:47

0 Answers0