Glengamoi (Forum) · AspHeute · .NET Heute (RSS-Suche) · AspxFiles (Wiki) · .NET Blogs
ASP German Homepage Homepage
 

Liste

.NET 2.0 (1)
.NET Allgemein (16)
.NET Fu (5)
ADO.NET (11)
Aprilscherz (3)
ASP Grundlagen (44)
ASP Tricks (83)
ASP.NET (44)
ASPIntranet.de (5)
C# (28)
Datenbank (44)
Dokumentation (4)
IIS 6.0 (1)
Komponenten (29)
Optimierung (10)
Server (21)
Sicherheit (34)
Tee Off (6)
VB.NET (6)
WAP (8)
Web Services (11)
XML (9)

RSS 2.0 - Die neuesten fünf Artikel auf AspHeute.com


 

Suchen





 

English Articles
Chinese Articles
Unsere Autoren
 
Link zu AspHeute
Impressum
Werben
Anfragen

Dateiupload mit ASP.NET und VB.NET

Geschrieben von: Christian Holm
Kategorie: VB.NET

Mit ASP war und ist es nicht möglich ohne eine zusätzlichen Dritthersteller-Komponente vernünftig Dateien auf einen Webserver upzuloaden. Mit ASP.NET steht eine solche Uploadkomponente von Haus aus zur Verfügung - gratis, und wie dieser Artikel zeigt, einfach in der Anwendung.

Wie gesagt, unter ASP benötigt man Fremdkomponenten, um mittels ASP Dateien am Webserver entgegennehmen zu können. ASP.NET bietet diese Funktionalität mit einer HTML Control namens HtmlInputFile, die sich von der bereits bekannten INPUT TYPE=FILE im Groben nur durch das RUNAT=SERVER Tag unterscheidet. Aber sie ist fixer Bestandteil des Produkts, managed den Upload für Sie, und verhält sich am Browser wie die normale Control die Sie bereits kennen.

In diesem Artikel stelle ich zwei Anwendungsfälle des Dateiuploads vor:

  • Upload in eine Datei
  • Upload unter Verwendung des FileStream Objektes

Bei ersterem Ansatz handelt es sich um die einfachste Lösung, der zweite demonstriert ein sehr flexibles Konzept wie man die Daten des Uploads selbst in Empfang nehmen und weiterverarbeiten kann.

Voraussetzung um den Sourcecode dieses Artikels verwenden zu können ist eine Installation des Microsoft .NET Framework SDK's auf einem Webserver. Weiters setze ich voraus, daß der Leser die Programmiersprache VB.NET zu einem gewissen Grad beherrscht.

Upload in eine Datei

Sehen Sie sich den nachfolgenden Screenshot an - solche Beispiele dürften Ihnen vom Dateiupload unter ASP auch bereits bekannt sein.

Obwohl es von "außen" nicht viel anders aussieht, so passiert unter der Haube doch etwas deutlich anderes als wir es von ASP gewohnt sind. Dazu werden wir jetzt den Sourcecode genauer ansehen (UploadFile.aspx):

<% @Page Language="VB" %>
<html>
<head>
    <script language="VB" runat="server">

       Sub btnUpload_Click(sender As Object, e As EventArgs) 
        
          If txtSaveAs.Value = "" Then
             txtInfo.InnerHtml = "Dateiname benötigt!"
             Return
          End If

          If Not IsNothing(File2Upld.PostedFile) Then
         
             Try
                File2Upld.PostedFile.SaveAs(txtSvrPath.Value + txtSaveAs.Value)
                txtInfo.InnerHtml = "Datei erfolgreich am Web Server auf <b>c:\Uploaded Files\" &_
                     txtSaveAs.Value & "</b> gespeichert"

             Catch Exc As Exception
                txtInfo.InnerHtml = "Fehler beim Speichern in <b>" & txtSvrPath.Value &_
                     txtSaveAs.Value & "</b><br>" & Exc.ToString
             End Try
          End If
       End Sub

    </script>

</head>
<body>

<form enctype="multipart/form-data" runat="server">

  <table border="0" cellpadding="2" cellspacing="2">
  <tr>
      <td>Datei: </td> 
      <td><input id="File2Upld" type=file runat="server"></td>
   </tr>
   <tr>
      <td>Web Server Pfad: </td>
      <td><input id="txtSvrPath" type="text" runat="server"></td>
   </tr>
   <tr>
      <td>Speichern als: </td>
      <td><input id="txtSaveAs" type="text" runat="server"></td>
   </tr>
   <tr>
      <td><input type=button id="btnUpload" 
                  value="Upload" OnServerClick="btnUpload_Click"
                  runat="server"></td>
   </tr>
</table>
  <span id=txtInfo runat="server" />

</form>

</body>
</html>

Betrachten wir für den Anfang nur das Formular, das die Datei (und den Namen, den sie am Server erhalten soll) an den Server schickt. Da wir gemischte Daten schicken, ist der enctype auf multipart/form-data gesetzt. Das ist noch nichts Neues. Das Einzige, das auf ASP.NET hinweist ist daß das Form am Server ausgeführt wird (RUNAT="SERVER").

In diesem Formular verwende ich im Gegensatz zum Artikel On-the-fly Generierung von Graphiken keine Web Controls, sondern HTML Controls - deswegen sieht es auch sehr vertraut aus. Allerdings würde man unter ASP sicher nicht das finden:

    <input type=button id="btnUpload" value="Upload" 
        OnServerClick="btnUpload_Click" runat="server">

Der Klick auf den Button löst am Server ein Event aus, das in der Funktion btnUpload_Click abgehandelt wird. Und somit sind wir beim Code, der notwendig ist, um eine Datei am Server erfolgreich abzuspeichern:

If Not IsNothing(File2Upld.PostedFile) Then
        
   Try
     File2Upld.PostedFile.SaveAs(txtSvrPath.Value + txtSaveAs.Value)
     txtInfo.InnerHtml = "Datei erfolgreich am Web Server auf <b>c:\Uploaded Files\" &_
         txtSaveAs.Value & "</b> gespeichert"

   Catch Exc As Exception
      txtInfo.InnerHtml = "Fehler beim Speichern in <b>" & txtSvrPath.Value &_
         txtSaveAs.Value & "</b><br>" & Exc.ToString
  
   End Try
   
End If

Das ist zwar nicht exakt der gesamte Sourcecode aus dem Beispiel, allerdings fehlt nur das "Rundherum" für die Namensvergabe am Server - der Fileupload funktioniert hier ebenso. Die if Abfrage überprüft, ob eine Datei gepostet wurde, indem sie die Eigenschaft PostedFile gegen die verneinte IsNothing Funktion prüft. Diese ist das Äquvivalent zu null in C#.

Wird eine Datei upgeloadet, so hält diese Eigenschaft eine gültige Referenz auf ein Objekt vom Typ HttpPostedFile, und ist somit verschieden von Nothing.

Nach diesem Sicherheitscheck bleibt uns "nur noch" die Datei zu speichern - ein simpler Aufruf der Funktion SaveAs auf dem Objekt HttpPostedFile erledigt alles für uns. Sollte etwas schiefgehen, wird unser Code darüber mit einer Exception benachrichtigt. So einfach ist es in ASP.NET eine Datei auf den Webserver zu laden.

Der Code im Beispiel selbst differiert nur dahingehend, daß die Datei einen benutzergewählten Namen erhalten kann. Dadurch ist er zwar etwas länger, aber bereits sehr flexibel. Der Weiterverwendung und Erweiterung in eigenen Projekten steht nichts im Wege.

Upload unter Verwendung des FileStream Objektes

So nett und schön das einfache Speichern der upgeloadeten Datei in eine Datei am Server auch sein kein, so oft möchte man mit den upgeloadeten Daten (den Bits) sofort wieder weiterarbeiten - ohne den Umweg in eine Datei. Anwendungsfälle wären etwa die Daten in die Datenbank zu speichern, die Daten zu parsen, oder irgendeine andere Bearbeitung durchzuführen.

Auch in diesem Fall läßt uns ASP.NET und das .NET Framework nicht im Stich. Anstatt die Kontrolle mit der SaveAs Funktion aus der Hand zu geben, kann man direkten Zugriff auf den FileStream der upgeloadeten Daten bekommen und mit diesen sofort weiterarbeiten - während der Upload passiert.

Das Beispiel, das ich zu Demonstrationszwecken gebastelt habe, erfüllt derzeit nur einen Zweck: die upgeloadeten Daten werden aus dem FileStream ausgelesen und in einer Stringvariablen zwischengespeichert - um dann einfach an den Client zurückgeschickt zu werden. Für Textuploads mag das bereits sinnvoll sein, bei binären Uploads (Bilder zum Beispiel) ist der Output nicht gerade überwältigend:

Der vorige Screenshot zeigt, daß mein Sourcecode (UploadFileStream.aspx) auch mit binären Daten - in diesem Fall ein kompiliertes C# Executable - korrekt umgehen kann. Dies erreiche ich durch eine erzwungene Konvertierung auf den ASCII-Zeichensatz. Die Details dazu können Sie dem Sourcecode und der folgenden Beschreibung entnehmen.

<html>

<script language="VB" runat="server">

Sub btnFileUpld_Click(sender As Object, e As EventArgs) 

  If Not IsNothing(txtFileName.PostedFile) Then
	
     Try 
		
       const BUFFER_SIZE As Integer = 255 
       Dim nBytesRead As Integer = 0
       Dim Buffer(BUFFER_SIZE) As Byte
       Dim strBFileContent As New StringBuilder("")	
       Dim FileStream As Stream = txtFileName.PostedFile.InputStream
			
       nBytesRead = FileStream.Read(Buffer, 0, BUFFER_SIZE)
			
         While 0 <> nBytesRead
	
           strBFileContent.Append(Encoding.ASCII.GetString(Buffer,0,nBytesRead))
           nBytesRead = FileStream.Read(Buffer,0,BUFFER_SIZE)
		
         End While		
        
           txtInfo.InnerHtml = strBFileContent.ToString()
	
     Catch Exc As Exception

               txtInfo.InnerHtml = "Fehler beim Speichern von <b>" + 
               txtFileName.PostedFile.FileName + "</b><br>"
               + e.ToString()

     End Try

   End If

End Sub

</script>

<body>

<table>
<form enctype="multipart/form-data" runat="server">
<tr>
  <td>Datei:</td>
  <td><input id="txtFileName" type=file runat="server"></td>
</tr>
<tr>
  <td colspan="2">
  <input type=button id="btnFileUpld" 
                            value="Speichern" 
                            OnServerClick="btnFileUpld_Click" 
                            runat="server">
  </td>
</tr>
</form>
</table>
    
<span id=txtInfo runat="server" />

</body>
</html>

Der Formularteil des Scripts ist bereits aus dem vorigen Listing bekannt, einzig und allein das Feld für die Namensgebung der Datei am Server fehlt - man braucht es nicht mehr. Was sind nun aber die Änderungen am Code für den Upload selbst? Im Grunde ist es nur dieser Part:

const BUFFER_SIZE As Integer = 255 

Dim nBytesRead As Integer = 0
Dim Buffer(BUFFER_SIZE) As Byte
Dim strBFileContent As New StringBuilder("")
Dim FileStream As Stream = txtFileName.PostedFile.InputStream
			
nBytesRead = FileStream.Read(Buffer, 0, BUFFER_SIZE)
			
While 0 <> nBytesRead
   strBFileContent.Append(Encoding.ASCII.GetString(Buffer,0,nBytesRead))
   nBytesRead = FileStream.Read(Buffer,0,BUFFER_SIZE)
End While		

Zuerst definiere ich eine Konstante, und instanziere darauffolgend drei Variablen, die in der Bearbeitung der Streamdaten benötigt werden: eine Variable, die die Anzahl der gelesenen Bytes speichert, der Puffer für die gelesenen Daten, und der StringBuilder, der dazu verwendet wird, um die auf ASCII konvertierten eingelesenen Streamdaten zu speichern.

Und dann beginnt die Action - zuerst hole ich mir eine Referenz auf den Stream, der über das Object HttpPostedFile zur Verfügung gestellt wird (dieses wiederum über die Eigenschaft PostedFile des HtmlInputFile Objects). Dadurch erspare ich mir weitere Zugriffe auf Eigenschaften und fremde Objekte, die nur die Rechenzeit verlängern würden.

Dann lese ich die ersten Daten ein, und steige damit in die While Schleife ein. Dort wird der Puffer auf ASCII Zeichensatz konvertiert, und die nächsten Daten eingelesen. Die While Schleife wird dann abgebrochen, wenn keine Daten mehr am Server angekommen sind.

Ist die While Schleife beendet, habe ich die Daten als String zur Weiterverarbeitung in der Hand - anstatt sie zurück an den Client zu schicken, könnte ich auch den String parsen - oder in eine Datenbank schreiben.

Übrigens: wenn man die unmodifizierten Binärdaten verwenden möchte, dann sollte man die Konvertierung auf ASCII unterlassen, und je nach Bedarf den richtigen "Zwischenspeicher" verwenden - ein großes Bytearray, einen MemoryStream oder eigene Datenstrukturen.

Schlußbemerkung

In diesem Artikel habe ich Ihnen zwei Methoden des Dateiuploads vorgestellt: das Speichern der upgeloadeten Datei am Server mit Hilfe der HtmlInputFile.PostedFile Property und der SaveAs Methode, sowie das direkte Auslesen der Daten mit Hilfe des FileStream Objekts. Erstere hat aber die Einschränkung, daß diese bei einer größeren Anzahl von Dateien umständlich wird. Der Grund liegt dabei in den Sicherheitsrichtlinien.

Download des Codes

Klicken Sie hier, um den Download zu starten.

Verwandte Artikel

Beliebige Anzahl von Dateien uploaden
Dateien auslesen mit VB.NET
Dateiupload mit ASP und WSC
Dateiupload mit ASP.NET
Web-basiertes Dateimanagement mit dem ASP FileMan

Wenn Sie jetzt Fragen haben...

Wenn Sie Fragen rund um die in diesem Artikel vorgestellte Technologie haben, dann schauen Sie einfach bei uns in den Community Foren der deutschen .NET Community vorbei. Die Teilnehmer helfen Ihnen gerne, wenn Sie sich zur im Artikel vorgestellten Technologie weiterbilden möchten.

Eine weitere sehr hilfreiche Resource ist das deutsche ASP.NET Wiki, das als zentrale Anlaufstelle für Tips, Tricks, Know How und alles Nützliche was man in seinem Alltag als (ASP).NET-Entwickler so braucht und entdeckt gedacht ist.

Haben Sie Fragen die sich direkt auf den Inhalt des Artikels beziehen, dann schreiben Sie dem Autor! Unsere Autoren freuen sich über Feedback zu ihren Artikeln. Ein einfacher Klick auf die Autor kontaktieren Schaltfläche (weiter unten) und schon haben Sie ein für diesen Artikel personalisiertes Anfrageformular.

 

Und zu guter Letzt möchten wir Sie bitten, den Artikel zu bewerten. Damit helfen Sie uns, die Qualität der Artikel zu verbessern - und anderen Lesern bei der Auswahl der Artikel, die sie lesen sollten.

Bewerten Sie diesen Artikel
 Sehr gut   Nicht genügend  
   1  2  3  4  5  
 

  
   Für Ausdruck optimierte Seite

©2000-2006 AspHeute.com
Alle Rechte vorbehalten. Der Inhalt dieser Seiten ist urheberrechtlich geschützt.
Eine Übernahme von Texten (auch nur auszugsweise) oder Graphiken bedarf unserer schriftlichen Zustimmung.