1

I'm writing a Windows Forms application in C# that allows a user to connect to a microcontroller and upload program files via FTP.

I can successfully upload program files via Filezilla. But when I run the code below I receive the error "The remote server returned an error: (451) Local error in processing." at the line "ftpstream.Close();" every single time no matter what file I try to upload, regardless of size or file type, and the new file does show up in Filezilla on the FiPy but with a size of 0 bytes.

I've erased all program files on the microcontroller so I know storage space is not the issue and I don't think its a firewall issue since I can upload successfully through Filezilla.

The WebException thrown shows no extra details in the InnerException and the StatusDescription comes back as an empty string.

I posted this question to the forum for the specific microcontroller I'm using but didn't get a solution. Here's the link to that post, it includes FTP logs and some solutions that were tried in the comments: https://forum.pycom.io/topic/6937/fipy-ftp-upload-in-c-returns-451-local-error-in-processing

I've exhausted all google results.

Can anyone help me out?

My code:

            var deviceFilepath = "ftp://192.168.4.1/flash/main.py";
            var appFilepath = "rwis\\main.py";

            string UserId = "micro";
            string Password = "python";

            FtpWebRequest ftp = (FtpWebRequest)FtpWebRequest.Create(deviceFilepath);
            ftp.Credentials = new NetworkCredential(UserId, Password);

            ftp.UsePassive = true;
            ftp.Method = WebRequestMethods.Ftp.UploadFile;

            var buffer = File.ReadAllBytes(appFilepath);

            Stream ftpstream = ftp.GetRequestStream();
            ftpstream.Write(buffer, 0, buffer.Length);
            ftpstream.Close();

EDIT:

FTP Log from Filezilla:

2021-04-09 09:36:52 3608 1 Status: Connecting to 192.168.4.1:21...
2021-04-09 09:36:52 3608 1 Status: Connection established, waiting for welcome message...
2021-04-09 09:36:52 3608 1 Response: 220 Micropython FTP Server
2021-04-09 09:36:52 3608 1 Status: Plain FTP is insecure. Please switch to FTP over TLS.
2021-04-09 09:36:52 3608 1 Command: USER micro
2021-04-09 09:36:52 3608 1 Response: 331 
2021-04-09 09:36:52 3608 1 Command: PASS ******
2021-04-09 09:36:52 3608 1 Response: 230 
2021-04-09 09:36:52 3608 1 Status: Server does not support non-ASCII characters.
2021-04-09 09:36:52 3608 1 Status: Logged in
2021-04-09 09:36:52 3608 1 Status: Retrieving directory listing...
2021-04-09 09:36:52 3608 1 Command: PWD
2021-04-09 09:36:52 3608 1 Response: 257 /
2021-04-09 09:36:52 3608 1 Status: Directory listing of "/" successful
2021-04-09 09:36:55 3608 1 Status: Retrieving directory listing of "/flash"...
2021-04-09 09:36:55 3608 1 Command: CWD /flash
2021-04-09 09:36:55 3608 1 Response: 250 
2021-04-09 09:36:55 3608 1 Command: TYPE I
2021-04-09 09:36:55 3608 1 Response: 200 
2021-04-09 09:36:55 3608 1 Command: PASV
2021-04-09 09:36:55 3608 1 Response: 227 (192,168,4,1,7,232)
2021-04-09 09:36:55 3608 1 Command: LIST
2021-04-09 09:36:55 3608 1 Response: 150 
2021-04-09 09:36:56 3608 1 Response: 226 
2021-04-09 09:36:56 3608 1 Status: Directory listing of "/flash" successful
2021-04-09 09:36:59 3608 1 Status: Starting upload of C:\Users\fcons_tzfi6gp\Documents\GitHub\production-assembly-app\bin\Debug\rwis\rwis_config.py
2021-04-09 09:36:59 3608 1 Command: TYPE A
2021-04-09 09:36:59 3608 1 Response: 200 
2021-04-09 09:36:59 3608 1 Command: PASV
2021-04-09 09:36:59 3608 1 Response: 227 (192,168,4,1,7,232)
2021-04-09 09:36:59 3608 1 Command: STOR rwis_config.py
2021-04-09 09:36:59 3608 1 Response: 150 
2021-04-09 09:36:59 3608 1 Response: 226 
2021-04-09 09:36:59 3608 1 Status: File transfer successful, transferred 1,361 bytes in 1 second

FTP Log from my code:

System.Net Information: 0 : [15404] FtpWebRequest#47891719::.ctor(ftp://192.168.4.1/flash/rwis_config.py)
System.Net Information: 0 : [15404] FtpWebRequest#47891719::GetRequestStream(Method=STOR.)
System.Net Information: 0 : [15404] FtpControlStream#16454088 - Created connection from 192.168.4.2:61116 to 192.168.4.1:21.
System.Net Information: 0 : [15404] Associating FtpWebRequest#47891719 with FtpControlStream#16454088
System.Net Information: 0 : [15404] FtpControlStream#16454088 - Received response [220 Micropython FTP Server]
System.Net Information: 0 : [15404] FtpControlStream#16454088 - Sending command [USER micro]
System.Net Information: 0 : [15404] FtpControlStream#16454088 - Received response [331 ]
System.Net Information: 0 : [15404] FtpControlStream#16454088 - Sending command [PASS ********]
System.Net Information: 0 : [15404] FtpControlStream#16454088 - Received response [230 ]
System.Net Information: 0 : [15404] FtpControlStream#16454088 - Sending command [OPTS utf8 on]
System.Net Information: 0 : [15404] FtpControlStream#16454088 - Received response [502 ]
System.Net Information: 0 : [15404] FtpControlStream#16454088 - Sending command [PWD]
System.Net Information: 0 : [15404] FtpControlStream#16454088 - Received response [257 /]
System.Net Information: 0 : [15404] FtpControlStream#16454088 - Sending command [TYPE I]
System.Net Information: 0 : [15404] FtpControlStream#16454088 - Received response [200 ]
System.Net Information: 0 : [15404] FtpControlStream#16454088 - Sending command [PASV]
System.Net Information: 0 : [15404] FtpControlStream#16454088 - Received response [227 (192,168,4,1,7,232)]
System.Net Information: 0 : [15404] FtpControlStream#16454088 - Sending command [STOR flash/rwis_config.py]
System.Net Information: 0 : [15404] FtpControlStream#16454088 - Received response [150 ]
System.Net Information: 0 : [15404] FtpControlStream#16454088 - Received response [451 ]
jeguyer
  • 2,379
  • 1
  • 11
  • 15
tw3399
  • 31
  • 5
  • Try using WebClient it can apparently upload to FTP though I've never used (and it likely uses FtpWebRequest). More notably Msft has abandoned FtpWebRequest and recommend to use third party libraries. – pinkfloydx33 Apr 08 '21 at 21:20
  • Indeed. See [Remarks](https://learn.microsoft.com/en-us/dotnet/api/system.net.ftpwebrequest?view=net-5.0#remarks): We don't recommend that you use the `FtpWebRequest` class for new development. For more information and alternatives to `FtpWebRequest`, see [`WebRequest` shouldn't be used](https://github.com/dotnet/platform-compat/blob/master/docs/DE0003.md) on GitHub. –  Apr 08 '21 at 21:25
  • While MS deprecated `FtpWebRequest`, it is still perfectly working. And `WebClient` uses `FtpWebRequest` under the hood. So switching to it is unlikely to help. + Show us log file both from FileZilla and [your .NET code](https://stackoverflow.com/q/9664650/850848). (both running at the same local maschine) – Martin Prikryl Apr 09 '21 at 07:21
  • Thank you for the responses! I tried WebClient and got the same result. It just came from the client.Upload() method and I thought that was less descriptive and less helpful than showing with FtpWebRequest that its coming exactly from the .Close() method. Edited my question to add the logs from Filezilla and my code. – tw3399 Apr 09 '21 at 13:46
  • "It just came from client.Upload()"..... it being the line that throws the error. Wanted to be more clear. – tw3399 Apr 09 '21 at 14:01
  • About your only real option is to break out Wireshark and trace what FileZilla is doing vs what the C# code is doing. My guess is that the FTP server on your microcontroller is doing something unusual that FileZilla handles properly but .NET does not. – Ian Kemp Apr 09 '21 at 14:23
  • FileZilla uploads the file in ascii mode. Did you try that in your code? – Another possibility is that the server cannot handle the path in `STOR flash/rwis_config.py`, while FileZilla does `CWD /flash` + `STOR rwis_config.py`. Nothing you can do about that. + Does your FTP server really return the code without any message (`[451 ]`)? Or did you edit the log? – Martin Prikryl Apr 09 '21 at 16:24
  • Is ascii mode when you set ftp.UseBinary to false? I've tried that and got the same error. Or is that not how you set ascii mode? Yeah I wondered if the path was the problem too but couldn't find a way to send a CWD command with ftpWebRequest. No, I didn't edit the log, it really doesn't give me an error message or anything helpful for fixing this problem. Ugh. – tw3399 Apr 09 '21 at 17:02
  • Yes `UseBinary=false`. As I write, you cannot make .NET send the `CWD` command. You might need to try another FTP client library. Try FluentFTP. – Martin Prikryl Apr 10 '21 at 04:42

1 Answers1

1

I got it to work with FluentFTP. I'm not 100% sure what the issue was, maybe using CWD fixed it, maybe some underlying logic/command in FluentFTP handled it better, either way, the FTP log now more closely matches the one from Filezilla and no more errors!

My New Code:

        FtpClient client = new FtpClient("ftp://192.168.4.1");
        client.Credentials = new NetworkCredential(UserId, Password);
        client.DataConnectionType = FtpDataConnectionType.PASV;
        client.Connect();
        client.SetWorkingDirectory("/flash");

        client.UploadFile(appFilepath, "rwis_config.py", FtpRemoteExists.NoCheck);

        client.Disconnect();

New FTP Log:

# Connect()
Status:   Connecting to ***:21
Response: 220 Micropython FTP Server
Command:  USER ***
Response: 331 
Command:  PASS ***
Response: 230 
Command:  FEAT
Response: 211 no-features
Status:   Text encoding: System.Text.ASCIIEncoding
Command:  SYST
Response: 215 UNIX Type: L8

# SetWorkingDirectory("/flash")
Command:  CWD /flash
Response: 250 

# UploadFile("rwis\rwis_config.py", "rwis_config.py", NoCheck, False, None)

# OpenWrite("rwis_config.py", Binary)
Command:  TYPE I
Response: 200 

# OpenPassiveDataStream(PASV, "STOR rwis_config.py", 0)
Command:  PASV
Response: 227 (192,168,4,1,7,232)
Status:   Connecting to ***:2024
Command:  STOR rwis_config.py
Response: 150 
Status:   Disposing FtpSocketStream...
Response: 226 
Status:   Testing connectivity using Socket.Poll()...
Command:  QUIT
Response: 221 
Status:   Disposing FtpSocketStream...
tw3399
  • 31
  • 5