3

I'm trying to programatically download a file in C# via FTP, here is the relevant code (obviously with fake credntials and URI):

try
{
    var request = FtpWebRequest.Create("ftp://ftp.mydomain.com/folder/file.zip");
    request.Credentials = new NetworkCredential("username", "password");

    using (var response = request.GetResponse())
    {
         ...
    }
}
catch (WebException we)
{
    ...
}

The exception is thrown at request.GetResponse(), and the error code is 550. The issue is not with the credentials or the URI, as they work just fine in IE and the file downloads successfully there. What am I missing? Is there some other kind of credential object I should be using? Is there a property on the request object I'm not setting? Any help would be appreciated.

gzak
  • 31
  • 1
  • 1
  • 2

6 Answers6

7

Turns out the FTP root isn't necessarily the same as the URL root. Perhaps I'm mixing up terminology, so let me explain: in my case, connecting to ftp.mydomain.com already starts at /folder, so my URL needed to just be ftp://ftp.mydomain.com/file.zip. IE8 knows how to eliminate the redundant /folder part in the original path while the FtpRequest class does not, which is why it worked in IE8 but not in the C# code.

gzak
  • 3,908
  • 6
  • 33
  • 56
  • 2
    This was my problem. I need to place a file in directory "upload", but on log in, the folder defaults to "download". When doing ftp by command line, "cd upload" automatically switched to "../upload". But the URL had to be ftp://ftp.mydomain.com/../upload/file.txt instead of ftp://ftp.mydomain.com/upload/file.txt – Lost In Code Nov 14 '11 at 23:49
  • I can give him a million upvotes... but I'd almost certainly lose my privileges. – Nick Larsen Aug 16 '12 at 00:37
4

Put another slash at the beginning of the local path part (after hostname:port):

var request = FtpWebRequest.Create("ftp://ftp.mydomain.com//folder/file.zip");

This has worked for me.

Miroslav Bajtoš
  • 10,667
  • 1
  • 41
  • 99
  • This worked for me as well, but I'm curious how you came up with this solution? – Nick Larsen Aug 16 '12 at 00:44
  • @NickLarsen Well I assumed that FtpWebRequest would parse the URL as ftp:///. Double slash means that starts with slash = path is absolute (i.e. relative to FTP root). – Miroslav Bajtoš Aug 16 '12 at 06:17
  • This is sooo weird. ftp://ftp.mydomain.com/folder1/folder2 works, but going deeper into the hierarchy i have to use ftp://ftp.mydomain.com//folder1/folder2/folder2/folder4... – Anders Bornholm Feb 14 '13 at 12:38
1

The Connection to my FTP-Server shows different behaviors, depending from where I try to connect. In my local Network it works with just one slash after the domain-part, e.g. ftp://test.test.com/folder/myfile.txt

But on a remote machine I have to use two slashes like ftp://test.test.com//folder/myfile.txt

The two-slashes-approach works in both cases.

Gerrit Horeis
  • 541
  • 5
  • 14
1

Here is what I use, I bet the .Method is the main thing you are missing

        request = (FtpWebRequest)FtpWebRequest.Create(address);
        request.Credentials = new NetworkCredential("username", "password");
        request.UsePassive = true;
        request.UseBinary = true;
        request.Proxy = null;

        request.Method = WebRequestMethods.Ftp.DownloadFile;
        FtpWebResponse dataResponce = (FtpWebResponse)request.GetResponse();
Scott Chamberlain
  • 124,994
  • 33
  • 282
  • 431
  • I would double and triple check that you do not have a capitalization or spelling error in your credentials. – Scott Chamberlain Dec 16 '10 at 20:44
  • quadruple checked, even copy-pasted repeatedly, no such luck unfortunately :-(. also, despite them being the defaults, i did actually try assigning those values to the properties as you suggested, just in case. again, no luck. – gzak Dec 16 '10 at 23:20
1

You have not set the Method.

 request.Method = WebRequestMethods.Ftp.DownloadFile;
Aliostad
  • 80,612
  • 21
  • 160
  • 208
  • I checked, `request.Method` is set to `WebRequestMethods.Ftp.DownloadFile` by default. – gzak Dec 16 '10 at 20:03
0

I recently had this problem and after much testing discovered that some module between here and there did not like a mixed case URI and so my resolution was to use .ToLower() on the URI