Dreizeiler: Dateien herunterladen mit .NET

Veröffentlicht: 14. Jun 2006
Von Mathias Schiffer

Das .NET Framework versorgt Sie mit allerlei Komfort. Viele früher komplexe Aufgaben werden so zum Kinderspiel. Dieser MSDN Quickie zeigt das für das Herunterladen von Dateien aus Inter- oder Intranet.

Früher war das Herunterladen von Dateien aus dem Inter- oder Intranet eine beschwerliche Angelegenheit. Überhaupt war der Kontakt per TCP/IP alleine bereits eine haarige Sache. Zu wenig war Windows darauf vorbereitet, dem Entwickler auf einfachste Weise Internetfunktionalität zugänglich zu machen.

Viel einfacher wird die Angelegenheit mit dem .NET Framework, das hier einiges an Boden gut gemacht hat. Der Namespace System.Net bietet diverse netzwerklastige Funktionen, auch an Intra-/Internetfunktionalität lässt sich hier erhebliche Unterstützung finden.

Das folgende Codebeispiel zeigt auf, wie einfach mit dieser Unterstützung eine Datei aus dem Internet heruntergeladen und als Datei abgespeichert werden kann: Es handelt sich um einen nur sprichwörtlichen „Dreizeiler“, also eine mit extrem wenigen Zeilen Code gelöste Aufgabe. Im konkreten Fall reichen sogar schon zwei Zeilen für die vormals komplexe Aufgabe:

' Ein neues WebClient-Objekt erzeugen
Dim webClient As System.Net.WebClient = New System.Net.WebClient
  
' Eine Datei per WebClient herunterladen und lokal speichern
webClient.DownloadFile("http://www.website.com/file.zip", "c:\file.zip")

Natürlich bleiben bei einem „Dreizeiler“ filigranere Möglichkeiten meist auf der Strecke. So entfallen hier etwa Möglichkeiten zur exakten Fehleranalyse ebenso wie etwa asynchrone Rückmeldungen zum aktuellen Abarbeitungsfortschritt, stückweise Downloads, Protokollfeinheiten und weitere Schmankerl.

Dennoch: Ein gewiefter Dreizeiler an der richtigen Stelle ist fast immer zumindest ein guter Start, der sich später bei Bedarf auch verfeinern lässt. Hier als Beispiel etwa eine um Fehlerbehandlung erweiterte Routine, die auch zusätzliche Header für den Webserver-Request sowie Benutzerdaten für kennwortgeschützte Downloads berücksichtigt:

Public Function DownloadFile(ByVal fileURL As String, _
                             ByVal fileSavename As String, _
                             Optional ByVal Username As String = Nothing, _
                             Optional ByVal Password As String = Nothing, _
                             Optional ByVal AdditionalHeaders() As String = Nothing _
                             ) As Boolean
  ' Lädt eine Datei von einem URL herunter und speichert sie als Datei.
  ' Gibt True zurück, wenn beim Herunterladen kein Fehler aufgetreten ist.
  ' Parameter:
  ' fileURL: URL der herunterzuladenden Datei
  ' fileSavename: Pfad der zu speichernden Datei
  ' OPTIONAL AdditionalHeaders: Array zusätzlicher Request-Header
  ' OPTIONAL Username: Benutzername für kennwortgeschützte Downloads
  ' OPTIONAL Password: Kennwort für kennwortgeschützte Downloads
  '
  ' Hinweis: Bei falsch konfigurierten Webservern kann es vorkommen, dass
  ' statt einer gewünschten Datei, die wegen eines Fehlers nicht herunterge-
  ' laden werden kann, eine Fehlerseite des Webservers heruntergeladen wird.
  
  Dim webClient As System.Net.webClient
  
  Try
  
    ' Ein neues WebClient-Objekt erzeugen
    webClient = New System.Net.webClient
  
    ' Zusätzliche Request-Header einfügen, sofern übergeben:
    If Not IsNothing(AdditionalHeaders) Then
      For Each hdr As String In AdditionalHeaders
        Call webClient.Headers.Add(hdr)
      Next
    End If
  
    ' Für kennwortgeschützte Download Benutezrnamen-/Kennwort-Kombinationen verwenden:
    If Not IsNothing(Username) Then
      If (Username.Length > 0) Then
        If IsNothing(Password) Then
          Password = ""
        End If
        webClient.Credentials = New System.Net.NetworkCredential(Username, Password)
      End If
    End If
  
    ' Antwort des Webservers anfordern, herunterladen und speichern:
    webClient.DownloadFile(fileURL, fileSavename)
    DownloadFile = True
    Exit Try
  
  Catch webex As System.Net.WebException ' HTTP-Fehler etc.
    Console.WriteLine ("Downloadfehler: " & webex.Message)
  
  Catch ex As Exception ' Andere Fehler
    Console.WriteLine ("Fehler: " & ex.Message)
  
  End Try
  
  ' Ressourcen freigeben
  webClient.Dispose()
  
End Function

Die WebException-Fehlerbehandlung der Methode wird bei HTTP-Fehlern angesprungen (etwa, wenn eine Datei auf dem Server nicht gefunden wurde). Dennoch sollten Sie bedenken, dass Sie hierfür strikt auf die Korrektheit serverseitiger Behandlung eines Fehlers angewiesen sind: Einige Webserver-Varianten kümmern sich um solche Feinheiten bedauerlicherweise nicht.

So kann es etwa passieren, dass Ihnen statt einer gewünschten ZIP-Datei ohne eine Fehlerauslösung die HTML-Fehlerseite des Webservers zum Download angereicht wird, die Sie bei analogem Vorgehen etwa auch in Ihrem Webbrowser sehen würden – eigentlich ein klassischer Fall für einen HTTP-Fehlercode. Hierbei handelt es sich keineswegs um einen Fehler im .NET Framework, sondern um fehlerhafte Konfigurationen der angesprochenen Webserver. Um diesem möglichen Problem beizukommen kann es sinnvoll sein, das als lokale Datei abgespeicherte Ergebnis des Downloads zu überprüfen. Auch die ResponseHeaders-Collection des WebClient-Objekts kann hierfür hilfreich sein.

Mathias Schiffer widmet sich als freier Technologievermittler und Entwickler großen Projekten ebenso wie arbeitserleichternden Alltagslösungen. Seit Jahren gibt er sein Wissen und seine Erfahrungen in unzähligen Publikationen und Beratungen auch an andere Entwickler und Entscheider weiter. Sie erreichen Mathias Schiffer per E-Mail an die Adresse Schiffer@mvps.org .


Anzeigen: