3

I am writing a program to copy files from a USB to an FTP server, and this is part of the code:

        private const string ftp_url = @"ftp://an_ip_addrs/X";

        private static void Upload(string sourceDir)
        {
            using (WebClient client = new WebClient())
            {
                try
                {
                    client.Credentials = new NetworkCredential(ftp_username, ftp_psw);

                    foreach (var filename in Directory.GetFiles(sourceDir))
                    {
                        Console.WriteLine("Preparing to upload --> " + filename);

                        client.UploadFile(ftp_url, WebRequestMethods.Ftp.UploadFile, filename);
                        Console.WriteLine("File Uploaded!");
                    }
                } catch (Exception e)
                {
                    Console.WriteLine("Err FTP --> " + e);
                }
            }
        }

This is the output from Preparing to upload:

Preparing to upload --> C:\Users\aimproxy\jn54comu\FASM - Copy (10).PDF

Actually I get this err from the try catch block:

"Err FTP -->  System.Net.WebException: The remote server returned an error: (553) File name not allowed.
   at System.Net.WebClient.UploadFile(Uri address, String method, String fileName)
   at System.Net.WebClient.UploadFile(String address, String method, String fileName)
   at usb_backdoor_csharp.Program.Upload(String sourceDir) in C:\Users\aimproxy\Desktop\Program.cs:line 29

As requested this is the Output from ftp.exe

Connected to 192.168.1.5.
220 Welcome to virtual FTP service.
503 USER expected.
User (192.168.1.5:(none)): upload
331 Password please.
230 User logged in.
ftp> dir
200 PORT 192.168.1.67:59392 OK
150 BINARY data connection established.
drwxrwxrwx   2 0        0        4096 Apr 22 18:07 X
226 Directory list has been submitted.
ftp: 135 bytes received in 0.02Seconds 7.50Kbytes/sec.
  • 1
    Have you taken a look at this post? https://stackoverflow.com/questions/9418404/cant-connect-to-ftp-553-file-name-not-allowed – Zenacity Apr 22 '19 at 18:01
  • @Zenacity Yeah I allready see this post, but I'm trying to upload to a folder and my folder is not the default destintion! –  Apr 22 '19 at 18:04
  • Does the folder exist in the remote? https://stackoverflow.com/questions/860638/how-do-i-create-a-directory-on-ftp-server-using-c – willaien Apr 22 '19 at 18:13
  • 3
    The server doesn't like the filename, which means that a) the server is not running Windows, and you're passing a Windows filename to it; or b) you're passing an invalid location for the file on the server. Neither of those issues can be resolved based on the information you've provided, because we don't know what OS the server is running and you've not provided a filename example that fails in your post. – Ken White Apr 22 '19 at 18:14
  • @willaien YES, the folder exists! –  Apr 22 '19 at 18:14
  • @KenWhite The server running on a linux machine, but it's an URL you can access via browser! –  Apr 22 '19 at 18:15
  • Then you can't upload to a Windows-style path. You'll have to send a Linux path to the location. – Ken White Apr 22 '19 at 18:16
  • 1
    What is `ftp://an_ip_addrs//X`? If you have removed some parts of the URL for privacy/security reasons, replace it with a sensible example. Not `//X`. – Martin Prikryl Apr 22 '19 at 18:18
  • X is the name folder @MartinPrikryl –  Apr 22 '19 at 18:19
  • @KenWhite Who I do that? –  Apr 22 '19 at 18:19
  • 1
    Start by removing the `//` before `//X` (you don't double forward slashes in a URL, only the one following the prototype). `ftp://` is correct, `an_ip_arrds//X` is not. – Ken White Apr 22 '19 at 18:21
  • @KenWhite same output –  Apr 22 '19 at 18:23
  • 2
    You may need to provide a `/` at the end (after the `/X`). If that doesn't work, then you'll need to [edit] your question to include the **actual path** you're using for the file, as well as the **actual filename** you're trying to upload. You're not providing any of the relevant details. Try using a command prompt and `ftp.exe` to see if you can get it to work from there to figure out the proper path and name, and then you'll know how it needs to look when your code sends it. – Ken White Apr 22 '19 at 18:25
  • 1
    Skimming some WebClient FileUpload examples it might actually want the full target filename for the upload URL, i.e. including the filename part and not just the folder to put it into. Although that seems strange to me and I can't see that explicitly in the docs. It does also say you can enable network trace to see exactly what the FTP client is doing which might be useful. – Rup Apr 22 '19 at 18:30
  • @KenWhite I upload the post with the output –  Apr 22 '19 at 18:31
  • If I change the FTP URL to `ftp://192.168.1.5/X/` , I get this `The requested URI is invalid for this FTP command.` –  Apr 22 '19 at 18:32
  • @Rup I update the post with the requested output! –  Apr 22 '19 at 18:37
  • 1
    I'd guess you want to append the filename to `ftp_url`. Try `client.UploadFile(Url.Combine(ftp_url, Path.GetFileName(filename)), filename)`. – Rup Apr 22 '19 at 18:41
  • Just FYI, you cannot ask people here to provide you help via TeamViewer or any other external means. All activity and help provided to you here must be done on this site in the question itself. If you want personalized remote assistance, hire a contractor to provide it. – Ken White Apr 22 '19 at 18:43
  • @Rup I got this `Url` does not contain a defenition for `Combine`, I already imported this `using System.Security.Policy;` You mean `Path.Combine` ?? –  Apr 22 '19 at 18:44
  • 1
    Sorry, read the wrong answer on an old question - Url.Combine is from a library. `client.UploadFile(new Uri(new Uri(ftp_url), Path.GetFileName(filename)), filename)`. ([based on this](https://stackoverflow.com/a/1527643/243245)) – Rup Apr 22 '19 at 18:46
  • @Rup Thanks this solution work `client.UploadFile(Path.Combine(ftp_url, Path.GetFileName(filename)), filename);``You can mark this as the solution! –  Apr 22 '19 at 18:51
  • @MartinPrikryl I do not agree with the fact that the question was marked with a duplicate, because the answer that Znaneswar gave does not resemble to Rup response! –  Apr 22 '19 at 20:15
  • But the answer by @RRM does! – Martin Prikryl Apr 22 '19 at 20:38
  • @MartinPrikryl Did you test on your computer? –  Apr 22 '19 at 21:10
  • @MartinPrikryl In addition NomadicDeveloper use WebRequst, but I use WebClient, is not the same thing! –  Apr 22 '19 at 21:37
  • What should I test on my computer? + `WebClient` internally uses `WebRequest`. Their URL format and error messages are the same. – Martin Prikryl Apr 23 '19 at 06:19

1 Answers1

1

The problem is that WebClient UploadFile expects a complete target file path, i.e. including the target filename. You're passing the target folder and expecting it to reuse the source filename - which is sensible, and I'm surprised doesn't work. It certainly isn't spelled out explicitly in the docs IMO.

As discussed in the comments, this worked for you:

client.UploadFile(Path.Combine(ftp_url, Path.GetFileName(filename)), filename);

I'd prefer an URL-combining function though, not a Path-combining function, e.g. from this old question - something like:

client.UploadFile(new Uri(new Uri(ftp_url), Path.GetFileName(filename)), filename);
Rup
  • 33,765
  • 9
  • 83
  • 112