How to get FTP server response on upload

Jul 23, 2014 at 9:54 PM
Hi,

I recently started using FtpClient library. So far so good. The only shortcoming I face now is not able to retrieve the server response after a successful file upload.

I am connecting to a Mainframe FTP server. Here is the response captured
FTP:Request from Port 2279,'STOR TEST#@$'
FTP:Response to Port 2279, '125  Sending Job to JES internal reader FIXrecfm 80'
FTP:Response to Port 2279, '250 -It is known to JES as JOB08630'
FTP:Response to Port 2279, '250  Transfer completed successfully.'
I am interested to display/parse the response code 125 and 250.
Coordinator
Jul 23, 2014 at 11:43 PM
If you can send me a transaction log from System.Net.FtpClient (see Examples\Debug.cs) I'll look into this further.

--
JP Trosclair


Jul 24, 2014 at 3:22 PM
Hi jptrosclair,

Thanks for quick reply. Here is the log. I just replaced the host name and username. What I am trying to do is to download a file, edit it and then put it back to Mainframe. I just want to make sure I capture the reply from server after uploading the file. Mainly these two lines
125 Sending Job to JES internal reader FIXrecfm 80
250-It is known to JES as JOB20556
220-FTPD1 IBM FTP CS V1R13 at ZZZZ, 14:14:31 on 2014-07-24.
220 Connection will close if idle for more than 5 minutes.
USER XXXXXXX
331 Send password please.
PASS <omitted>
230 XXXXXXX is logged on.  Working directory is "XXXXXXX.".
FEAT
211- Extensions supported
 SIZE
 MDTM
 REST STREAM
 UTF8
 LANG en*
 AUTH TLS
 AUTH GSSAPI
 CCC
 PBSZ
 PROT
211 End
OPTS UTF8 ON
501 command OPTS aborted -- no options supported for UTF8
Text encoding: System.Text.UTF8Encoding
TYPE A
200 Representation type is Ascii NonPrint
SIZE 'GDOC.MPHTST.OPI.UTILS.JCLCARD(EUICNRCN)'
550 command SIZE rejected - 'GDOC.MPHTST.OPI.UTILS.JCLCARD(EUICNRCN)' is not an HFS file
EPSV
229 Entering Extended Passive Mode (|||9108|)
RETR 'GDOC.MPHTST.OPI.UTILS.JCLCARD(EUICNRCN)'
125 Sending data set GDOC.MPHTST.OPI.UTILS.JCLCARD(EUICNRCN) FIXrecfm 80
250 Transfer completed successfully.
SITE FILEtype=JES
200 SITE command was accepted
TYPE A
200 Representation type is Ascii NonPrint
SIZE TEST#@$
550 command SIZE fails: filetype is JES
EPSV
229 Entering Extended Passive Mode (|||9109|)
STOR TEST#@$
125 Sending Job to JES internal reader FIXrecfm 80
250-It is known to JES as JOB20556
250 Transfer completed successfully.
Disposing FtpSocketStream...
Disposing FtpSocketStream...
Disposing FtpClient object...
QUIT
221 Quit command received. Goodbye.
Disposing FtpSocketStream...
Disposing FtpSocketStream...
Disposing FtpSocketStream...
Disposing FtpClient object...
Coordinator
Jul 25, 2014 at 2:57 AM
Alright, the latest commit has a few things you'll be interested in. To use them cast the Stream object to a FtpDataStream. That should give you access to the public property CommandStatus which is a FtpReply object saved from the command used to open the data stream (STOR in the example above, so the 125 message after). This is actually an old property used internally in System.Net.FtpClient so don't change it unless you understand the consequences. The other change is the Close() method of the stream should now return the response that's read when the stream is closed, so the 250 messages you want. A better example:
static void StreamResponses() {
            using (FtpClient cl = new FtpClient()) {
                cl.Credentials = new NetworkCredential(m_user, m_pass);
                cl.Host = m_host;
                cl.EncryptionMode = FtpEncryptionMode.None;

                using (FtpDataStream s = (FtpDataStream)cl.OpenWrite("test.txt")) {
                    FtpReply r = s.CommandStatus;

                    Console.WriteLine();
                    Console.WriteLine("Response to STOR:");
                    Console.WriteLine("Code: {0}", r.Code);
                    Console.WriteLine("Message: {0}", r.Message);
                    Console.WriteLine("Informational: {0}", r.InfoMessages);

                    r = s.Close();
                    Console.WriteLine();
                    Console.WriteLine("Response after close:");
                    Console.WriteLine("Code: {0}", r.Code);
                    Console.WriteLine("Message: {0}", r.Message);
                    Console.WriteLine("Informational: {0}", r.InfoMessages);
                }
            }
        }
Marked as answer by mannbiher on 7/25/2014 at 8:22 AM
Coordinator
Jul 25, 2014 at 2:59 AM
If you need more than that you'll want to hook in with a trace listener to monitor the server activity; basically parse the responses yourself.
Marked as answer by mannbiher on 7/25/2014 at 8:22 AM
Jul 25, 2014 at 4:22 PM
Hi jptrosclair,

Thanks for quick response. I would try both options and see which works best for me.

Also thanks for the wonderful library for free. You rock... :)
Coordinator
Jul 26, 2014 at 4:14 AM
No problem I hope these changes do what you needed.