This project is read-only.

GetListing() returns an empty list while there are items available...

Dec 17, 2012 at 8:50 AM

Hi,

I'm trying to use the library and it's working fine except the GetListing command. It always returns an empty list while there are items on my ftp server. -> {System.Net.FtpClient.FtpListItem[0]}

My testing code:

        using (_ftpClient = new FtpClient())
        {
          _ftpClient.Host = FtpUrl;
          _ftpClient.Credentials = new NetworkCredential(FtpUser, FtpPwd);
          _ftpClient.Connect();

          if (_ftpClient.IsConnected) 
          {
            StatusText = "Connection successfull!";
            //StatusText = _ftpClient.GetWorkingDirectory(); // gets the working dir
          }
          else 
            StatusText = "Connection not successfull!";

          if (!string.IsNullOrEmpty(WorkingDir) && _ftpClient.DirectoryExists(WorkingDir))
          {
            _ftpClient.SetWorkingDirectory(WorkingDir); // sets the working dir
            StatusText = _ftpClient.GetWorkingDirectory();
          }

          string wd = _ftpClient.GetWorkingDirectory();
          string newWd = _ftpClient.GetWorkingDirectory() + "/blabla2";

          _ftpClient.CreateDirectory(newWd); // creates a new directory
          _ftpClient.DeleteDirectory(newWd, true, FtpListOption.AllFiles | FtpListOption.ForceList); // deletes a directory

          string f = _ftpClient.GetWorkingDirectory() + @"/c#_codingStandards.pdf";
          var s = _ftpClient.GetFileSize(f); // gets the filesize of a file

          var items = _ftpClient.GetListing(wd, FtpListOption.Modify | FtpListOption.Size); // doesn't return any item while there are lots of items on the server in this folder...
          foreach (FtpListItem item in items)
          {

            switch (item.Type)
            {
              case FtpFileSystemObjectType.Directory:
                MessageBox.Show(item.Name);
                break;
              case FtpFileSystemObjectType.File:
                MessageBox.Show(item.Name);
                break;
            }
          }

        }

Can anyone tell me what I'm dong wrong? 

Thx!

Coordinator
Dec 17, 2012 at 11:34 AM

Read the documentation about debugging the code. What's probably happening is the listing format can't be parsed. Only way to know for sure is to get a transaction log and in order to fix it you'll probably need to add a custom parser which is also covered in the documentation.

Dec 18, 2012 at 2:29 PM

Isn't it a bug if a function in your class doesn't work as it should without even raising an error? Or is it just me?

If I use the function provided in the class to retrieve a list of files on the server I expect this to do so, or at least throw some kind of error...

Coordinator
Dec 18, 2012 at 3:26 PM
Edited Dec 18, 2012 at 3:26 PM

There is no written spec on how a LIST command should be formatted or even what the server should send back. The server response could include any arbitrary text that can't be parsed along with text that can be parsed. How do I reliably determine that something is wrong with a file listing when the status codes from the server say otherwise?

Coordinator
Dec 18, 2012 at 8:51 PM

Revision 217e9323dc49 has a new set of methods for the NLST command which I think you may find more reliable. There are examples of using the new GetNameListing() method as well as its async counterparts in the Examples project of the source tree. Here's a quick example of using to retrieve much of the same information you would get from GetListing() if it was parsing the file listing correctly:

using (FtpClient cl = new FtpClient()) {
                cl.Credentials = new NetworkCredential(m_user, m_pass);
                cl.Host = m_host;
                cl.Connect();

                foreach (string s in cl.GetNameListing()) {
                    Console.WriteLine("{0} {1} {2}",
                        cl.DirectoryExists(s) ? "Dir" : "File",
                        cl.GetFileSize(s),
                        cl.GetModifiedTime(s));
                }
            }
This process will be slower than parsing LIST results however it should also be about as reliable as you can ask for within the constraints outlined by RFC959.

Coordinator
Dec 18, 2012 at 10:05 PM
Edited Dec 18, 2012 at 10:06 PM

Revision ac6e6ff70446 adds support for NLST to GetListing() so you can retrieve FtpListItem objects as before. Example usage:

 

client.GetListing(path, FtpListOption.SizeModify | FtpListOption.NameList)

The example above will use NLST when MLSD isn't available. In addition, the SizeModify tells it to determine file sizes and modified times using the GetFileSize() and GetModifiedTime() methods. MLSD is much more efficient way to perform directory listings however you can also opt not to use it by using the ForceNameList flag instead of NameList.

Dec 19, 2012 at 2:51 PM

Great thx!!! I'll try this asap..

Dec 20, 2012 at 10:52 AM

Hi,

In the meantime I've created my own parser, or actually copied your ParseMachineList parser and modified it to fit my needs and now the GetListing() method works fine.. Also tested the GetNameListing() and that does also work.

Thx for your patience, it's the first time I use ftp with C# so need a lot to figure out.

Grts!

Coordinator
Dec 20, 2012 at 11:37 AM
I'm glad that you got it working. If you don't mind sharing a sample of the file list that couldn't be parsed I'd appreciate it so that I can fix the built-in parser. Machine listing should mostly be the same so this is very likely a bug in System.Net.FtpClient rather than a quirk in the formatting of a particular server. What server software also?
Dec 20, 2012 at 12:35 PM

Here you'll find some responses from the server. It's from my provider so I don't have a clue what server it is. I use that ftp to test my application and playing with your ftp class. Any idea how i can find out what type of server it is? When I connect with FileZilla I see this: 215 UNIX Type: L8

It are just some dummy files and folders:

modify=20121220122116;perm=flcdmpe;type=dir;unique=32U42C40C;UNIX.group=110;UNIX.mode=02755;UNIX.owner=662139; .
modify=20121215214324;perm=flcdmpe;type=dir;unique=32U3A2000;UNIX.group=110;UNIX.mode=02755;UNIX.owner=662139; ..
modify=20121215215742;perm=adfrw;size=89018;type=file;unique=32U42C40D;UNIX.group=110;UNIX.mode=0644;UNIX.owner=662139; flag.pdn
modify=20121215215742;perm=adfrw;size=69961;type=file;unique=32U42C40E;UNIX.group=110;UNIX.mode=0644;UNIX.owner=662139; mask.png
modify=20121215215743;perm=adfrw;size=134355;type=file;unique=32U42C40F;UNIX.group=110;UNIX.mode=0644;UNIX.owner=662139; plafonds.docx
modify=20121215215743;perm=adfrw;size=13358;type=file;unique=32U42C410;UNIX.group=110;UNIX.mode=0644;UNIX.owner=662139; Afwerking_schakelaars_erondegem.xlsx
modify=20121215215744;perm=adfrw;size=233297;type=file;unique=32U42C411;UNIX.group=110;UNIX.mode=0644;UNIX.owner=662139; c#_codingStandards.pdf
modify=20121215215759;perm=flcdmpe;type=dir;unique=32U42C600;UNIX.group=110;UNIX.mode=02755;UNIX.owner=662139; subfolder
modify=20121215223422;perm=flcdmpe;type=dir;unique=32U40AC06;UNIX.group=110;UNIX.mode=02755;UNIX.owner=662139; subfolder2

Coordinator
Dec 20, 2012 at 12:50 PM
That's the result of the SYST command, no way to really tell unless it advertises it when you connect.
Coordinator
Dec 20, 2012 at 1:33 PM

Well the bug should be fixed in the latest revision. The machine list parser expected type= to come at the start of the line and as we see here it didn't. I've corrected this assumption.

Dec 20, 2012 at 2:29 PM

I guess that I don't need my own parser anymore :)

I've got another question. I want to download those files in the list and it works well untill after the 4th file, then I get an error saying I have exceeded the max allowed connections(5) for this user. Is it best I start a new threat for this?

Grts!

Coordinator
Dec 20, 2012 at 2:43 PM

You can try setting EnableThreadSafeDataConnections = false if you don't need multi-threaded capabilities. What's happening is the server is limiting the number of concurrent connections you can make. This is not an uncommon configuration. Thread safe data channels work by cloning the FtpClient object and creating a new control connection. This is necessary in threaded code because you can't do anything on the control connection while a download or upload is in progress.