System.Net.FtpClient
Auf dieser Seite gibt es einen kurzen Erfahrungsbericht über das Arbeiten mit der C# Library System.Net.FtpClient:

Was ist System.Net.FtpClient?

System.Net.FtpClient ist eine .NET-Library, die man für C# Applikationen verwenden kann, um eine Verbindung zu einem FTP-Server aufzustellen und dann Dateien zu transferieren.

Ich wurde auf diese Library über diese StackOverflow Seite aufmerksam, nachdem meine Recherchen über die FtpWebRequest Klasse vom .NET Framework keine zufriedenstellenden Ergebnisse lieferten. (Mit der FtpWebRequest Klasse müssen alle Aktionen, die durchgeführt werden in die URL codiert werden. Ein Beispiel dazu habe ich hier gefunden. Das heißt, man kann keine Verbindung zum FTP-Server aufbauen und dann Inhalte abrufen oder raufladen, sondern man muss jede Aktion in den Request programmieren.)

Wie bindet man System.Net.FtpClient in ein C# Projekt ein?

Folgende Schritte sind umzusetzen:
  • Auf das Download Register auf der Projektseite von System.Net.FtpClient wechseln und die Datei System.Net.FtpClient.xx.xx.xx.zip runterladen.
  • Die Zip-Datei entpacken und die darin enthaltene System.Net.FtpClient.dll (z.B. im Verzeichnis bin/Release) in das bin-Verzeichnis der ASP.NET Applikation kopieren.
  • In den C# Dateien, in denen die Funktionalität der Library verwendet werden soll, ist eine using Anweisung hinzuzufügen. Bisher habe ich nur folgende Packages benötigt:
                using System.Net.FtpClient;
              
  • Beim Kompilieren der Sourcen, die zusätzliche DLL-Datei als Referenz hinzufügen mit /r:bin\System.Net.FtpClient.dll.

    So ergab sich beispielsweise folgende Anweisung bei mir:
    C:\WINDOWS\Microsoft.NET\Framework\v4.0.30319\csc /target:library /r:bin\System.Net.FtpClient.dll /out:bin\FileUpload.dll src\FileUpload\*.cs

Code-Beispiele

Für mein Projekt habe ich Dateien auf den FTP-Server geladen und auf eine Anfrage wieder vom FTP-Server gelesen und als E-Mail Attachment verschickt.

Dafür habe ich mir zwei Klassen geschrieben, welche auf Funktionalitäten der System.Net.FtpClient Library zugreifen.
  • FtpSession.cs - Damit wird eine Verbindung mit dem FTP-Server aufgebaut, man kann in andere Verzeichnisse wechseln, Dateien auf den Server laden und auch Dateien runterladen.
  • MyFtpFile.cs - Ist eine Klasse, welche den File-Inhalt als MemoryStream und Datei-Informationen wie Name, Größe und Änderungsdatum kapselt.

Code-Beispiele aus der FtpSession Klasse

Aufbau einer Verbindung zum Server
      m_pConnection = new FtpClient();
      m_pConnection.Host = pServer;
      m_pConnection.Credentials = new NetworkCredential(pUser, pPassword);
      m_pConnection.Connect();
      
Dabei ist m_pConnection eine Membervariable vom Typ FtpClient. Die Parameter pServer, pUser und pPassword sind vom Typ string und wurden aus der Konfiguration eingelesen.

Ändern des Verzeichnisses
      m_pConnection.SetWorkingDirectory(m_pWorkingDirectory);
      
Dabei ist m_pWorkingDirectory eine Membervariable vom Typ string.

Erstellen eines Verzeichnisses
      bool bExists = m_pConnection.DirectoryExists(pDirectoryName);
      if (!bExists) m_pConnection.CreateDirectory(pDirectoryName);
      
Dabei ist pDirectoryName eine Variable vom Typ string.

Raufladen einer Datei
      public void UploadFile(string pFileName, Stream pInputStream) {
        //1. make some checks
        pFileName = Utilities.PrepareString(pFileName);
        if (pFileName.Equals("")) return;
        if (pInputStream == null) return;
      
        //2. upload
        using (Stream pOutputStream = m_pConnection.OpenWrite(pFileName)) {
          try {
            pInputStream.CopyTo(pOutputStream); //since .NET 4.0
          }
          finally {
            pOutputStream.Close();
          }
        }
      }
      


Raufladen einer Datei (Erstellen eines MyFtpFile Objekts)
        public MyFtpFile GetFtpFile(string pFileName) {
          pFileName = Utilities.PrepareString(pFileName);
          if (pFileName.Equals("")) return null;
          
          MyFtpFile pFtpFile = null;
          FtpListItem pObjectInfo = GetFileInformation(pFileName);
          using(Stream pInputStream = m_pConnection.OpenRead(pFileName)) {
            try {
              pFtpFile = new MyFtpFile(pInputStream, pObjectInfo);
            }
            catch (Exception pException) {
              throw new Exception("The file " + pFileName + 
              " could not be fetched! " + pException.Message);
            }
            finally {
              pInputStream.Close();
            }
          }
          return pFtpFile;
        }
      


Verbindung zum FTP-Server schließen
        m_pConnection.Disconnect();
      

Code-Beispiele aus der MyFtpFile Klasse

Übertragen der Informationen in Membervariablen
      /*** member variables ***/
      private MemoryStream m_pStream;
      private string m_pFullName, m_pName;
      private DateTime m_pModified, m_pCreated;
      private long m_lSize; 
      
      ///////////////////////////////
      // CONSTRUCTOR               //
      ///////////////////////////////
      public MyFtpFile(Stream pInputStream, FtpListItem pItem) {
        //1. make some checks
        if (pInputStream == null) 
          throw new ArgumentNullException("No input stream!");
        if (pItem == null) 
          throw new ArgumentNullException("No ftp item information!");
        
        //2. copy the stream
        m_pStream = new MemoryStream();
        pInputStream.CopyTo(m_pStream);
        
        //3. copy the information
        m_pFullName = pItem.FullName;
        m_pName = pItem.Name;
        m_pModified = pItem.Modified;
        m_pCreated = pItem.Created;
        m_lSize = pItem.Size;
      }
      


Umwandlung der Informationen in ein E-Mail Attachment
      public Attachment GetAttachment() {
    
        m_pStream.Seek(0, SeekOrigin.Begin);
        Attachment pAttachment = 
          new Attachment(m_pStream, MediaTypeNames.Application.Octet);
        
        ContentDisposition pDisposition = pAttachment.ContentDisposition;
        pDisposition.CreationDate = m_pCreated;
        pDisposition.ModificationDate = m_pModified;
        pDisposition.ReadDate = DateTime.Now;
        pDisposition.FileName = m_pName;
        pDisposition.Size = m_lSize;
        pDisposition.DispositionType = DispositionTypeNames.Attachment;
        return pAttachment;
      }