ASCII Encoding issue on upload

Aug 22, 2013 at 3:14 PM
Edited Aug 22, 2013 at 3:53 PM
We are trying to upload ASCII files to a IBM ZOS mainframe. It seems that regardless of what we pass to the SetDataType method, the contents of the file are garbled. The download from the ZOS using ASCII DataType works fine.

I see that there is a read only property called Encoding. This may be what is affecting us.
How could this be used? Any ideas?

Thanks
Coordinator
Aug 22, 2013 at 3:27 PM
The Encoding property is either ASCII or UTF8 and it's set according to the server. It defaults to ASCII and if the server supports UTF8, UTF8 is enabled and the encoding is switched over, otherwise it's always Encoding.ASCII. That said, the data streams returned from OpenRead() and OpenWrite() are raw, there is no internal conversion going on by System.Net.FtpClient when you read or write regardless of TYPE I or TYPE A, the data is read or sent as-is.
Coordinator
Aug 22, 2013 at 3:46 PM
If you don't mind, post the transaction log from one of the uploads where the result is garbled.
Aug 22, 2013 at 3:55 PM
jp, we don't have access to the mainframe, it's owned by another company. When we perform the ASCII uploads using WSFTP Pro, the upload works fine. FYI, we are using Explicit SSL.
Coordinator
Aug 22, 2013 at 3:56 PM
I meant the transaction log form System.Net.FtpClient, see the Examples\Debug.cs file for more information.
Aug 22, 2013 at 3:59 PM
p.s. I do see 2 separate places where encoding is initialized
    Encoding m_textEncoding = Encoding.ASCII;
and
    m_textEncoding = Encoding.Default;
I commented out the 2nd one but it made no difference.

For uploading I do this:


private void Put(string localFileName, string remoteFileName)
    {
        using (
                        Stream istream = new FileStream(localFileName, FileMode.Open, FileAccess.Read),
                        ostream = ftp1.OpenWrite(remoteFileName))
        {
            byte[] buf = new byte[8192];
            int read = 0;

            try
            {
                while ((read = istream.Read(buf, 0, buf.Length)) > 0)
                {
                    ostream.Write(buf, 0, read);
                }
            }
            finally
            {
                ostream.Close();
                istream.Close();
            }
        }
    }
Coordinator
Aug 22, 2013 at 4:18 PM
As I said, the Encoding property is not used in file transfers. It's used for talking with the server on the control connection and getting file listings in the appropriate text encoding. The Reads() and Writes() on the streams returned from OpenRead(), OpenWrite() and OpenAppend() are not modified internally by System.Net.FtpClient in any way.

Just for the sake of testing, try executing the following code before you do an upload and tell me if it makes a difference:
FtpReply reply = ftp1.Execute("STRU R");
if(!reply.Success) {
 throw new FtpCommandException(reply);
}
Coordinator
Aug 22, 2013 at 4:19 PM
Also set EnableThreadSafeDataChannels = false and execute it right above the OpenWrite() call.
Aug 22, 2013 at 4:29 PM
Edited Aug 22, 2013 at 4:32 PM
I just realized (by looking through the libs code) that the OpenWrite and OpenRead methods default the DataType to Binary regardless of what the DataType was set to at the time of connection.....I am now trying to explicitly pass DataType.ASCII at the time of OpenWrite. Strange that the Download which uses OpenRead works fine.
Coordinator
Aug 22, 2013 at 4:38 PM
That's right, I thought SetDataType() was protected, it's only supposed to be used internally. You need to pass it with each call to OpenRead() and OpenWrite(). Any how, the latest revision also adds the STRU command for changing the structure type to Record when you use ASCII, or File when you use binary. This might also clear up some of the issue. Let me know if the problem is fixed.
Aug 22, 2013 at 9:20 PM
jp, it looks like this was the issue, the downloads are now working.

Thanks for the help.
Coordinator
Aug 22, 2013 at 9:21 PM
No problem. I pushed up an update an SetDataType() is now a protected method. Did setting the STRUcture or changing your OpenRead() call to include ASCII fix it?
Aug 22, 2013 at 10:10 PM
Just using the overload that takes the DataType param did it.