Dateiupload in ein Verzeichnis

 

 

Autor: Jürgen Gutsch

Version: 1.0

Sprache: vb.net

 

Benötigt wird:

.net Framework ab v1.x.xxxx

VisualStudio.net

 

Getestet auf winXP-Professional (IIS 5.1)

 

 

Dateiupload in ein Verzeichnis

 

Was früher mit ASP, ohne Komponenten oder aufwendigen Scripts nicht möglich war, ist heute mit .net kein Problem mehr. Dateien, die über ein Html-Formular an den Server gesendet werden, können direkt aus dem Http-Haeder ausgelesen und weiterverarbeitet werden. Dieses Tutorial zeigt eine uploadroutine für mehrere Dateien (die allerdings auch problemlos mit einem Formularfeld vom Typ "file" functioniert).

 

 

Das Formular

 

Legen wir als erstes eine aspx-Seite "upload.aspx" im VisualStudio an.

Sie sollte in etwa so aussehen:

<%@ Page Language="vb" AutoEventWireup="false" 
    Codebehind="upload.aspx.vb" Inherits="tutorials.upload"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
<title>WebForm1</title>
<meta name="GENERATOR" content="Microsoft Visual Studio.NET 7.0">
<meta name="CODE_LANGUAGE" content="Visual Basic 7.0">
<meta name="vs_defaultClientScript" content="JavaScript">
<meta name="vs_targetSchema" 
            content="http://schemas.microsoft.com/intellisense/ie5">
</head>
<body>
<form id="Form1" method="post" runat="server"></form>
</body>
</html>

 

Das Form-Tag ergänzen wir um ein Attribut:

enctype="multipart/form-data"

Um auch Binärdaten zu senden.

 

Zwischen die Form-Tags setzen wir die benötigten Steuerelemente, so dass die aspx-Seite jetzt etwa so aussieht:

<%@ Page Language="vb" AutoEventWireup="false" 
    Codebehind="upload.aspx.vb" Inherits="tutorials.upload"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
<title>WebForm1</title>
<meta name="GENERATOR" content="Microsoft Visual Studio.NET 7.0">
<meta name="CODE_LANGUAGE" content="Visual Basic 7.0">
<meta name="vs_defaultClientScript" content="JavaScript">
<meta name="vs_targetSchema" 
            content="http://schemas.microsoft.com/intellisense/ie5">
</head>
<body>
<form id="Form1" method="post" runat="server" 
            enctype="multipart/form-data">
<input type="file" name="file1" id="file1" runat="server" /><br />
<input type="file" name="file2" id="file2" runat="server" /><br />
<input type="file" name="file3" id="file3" runat="server" /><br />
<input type="file" name="file4" id="file4" runat="server" /><br />
<input type="file" name="file5" id="file5" runat="server" /><br />
<input type="file" name="file6" id="file6" runat="server" /><br />
<input type="submit" name="send" id="send" 
            runat="server" value="submit" />
<br />
<asp:label id="Label1" runat="server"></asp:label>
</form>
</body>
</html>

 

Damit währe unser Testformular vollständig.

 

 

Die Codebehind-Klasse

 

Um in die Codeansicht zu wechseln, klicken wir mit der rechten Maustaste in auf die aspx-Seite und wählen "Code anzeigen".

 

Folgender Code sollte vom VisualStudio angelegt worden sein:

Public Class upload
    Inherits System.Web.UI.Page
    Protected WithEvents file1 As _
                System.Web.UI.HtmlControls.HtmlInputFile
    Protected WithEvents file2 As _ 
                System.Web.UI.HtmlControls.HtmlInputFile
    Protected WithEvents file3 As _
                System.Web.UI.HtmlControls.HtmlInputFile
    Protected WithEvents file4 As _
                System.Web.UI.HtmlControls.HtmlInputFile
    Protected WithEvents file5 As _
                System.Web.UI.HtmlControls.HtmlInputFile
    Protected WithEvents file6 As _
                System.Web.UI.HtmlControls.HtmlInputFile
    Protected WithEvents Label1 As _
                ystem.Web.UI.WebControls.Label
    Protected WithEvents send As _
                System.Web.UI.HtmlControls.HtmlInputButton
	
    #Region " Web Form Designer Generated Code "

        'This call is required by the Web Form Designer.
        <System.Diagnostics.DebuggerStepThrough()> _
        Private Sub InitializeComponent()

        End Sub

        Private Sub Page_Init(ByVal sender As System.Object, _
                ByVal e As System.EventArgs) Handles MyBase.Init
            'CODEGEN: This method call is required 
            'by the Web Form Designer
            'Do not modify it using the code editor.
            InitializeComponent()
        End Sub

    #End Region

    Private Sub Page_Load(ByVal sender As System.Object, _
            ByVal e As System.EventArgs) Handles MyBase.Load
        'Put user code to initialize the page here

    End Sub

End Class

 

Fügen wir dem oben stehenden Code nun die Prozedur hinzu, die den Uploadübernimmt:

[...]
Private Sub saveInFolder()

End Sub
[...]

 

Alles weitere geschieht jetzt innerhalb dieser Sub

 

So auch die nächste Zeile:

Hier Deklarieren wir eine Variable (FileCollection) vom Typ System.Web.HttpFileCollection, welche alle Übertragenen Dateien empfängt (Request.Files):

Dim FileCollection As System.Web.HttpFileCollection = Request.Files

 

als nächstes benötigen wir noch einige Variablen:

Dim i As Integer ' ein Counter

Dim ContentLength As Long ' speichert die Dateigröße
Dim FileName As String ' speichert den Dateinamen
Dim IOStream As System.IO.Stream ' empfängt die Datei

Dim Counter As Integer ' Zählt die Dateien

 

es folgt die Schleife, um alle dateien in der FileCollection auszulesen, sowie das Auslesen der Dateieigenschaften ContentLength und Filename:

For i = 0 To FileCollection.Count - 1
    IOStream = FileCollection(i).InputStream
    ContentLength = FileCollection(i).ContentLength
    FileName = System.IO.Path.GetFileName(FileCollection(i).FileName)

Man sollte hierbei mal einen Blick auf die Function GetFileName im Namespace System.IO.Path werfen, die einen aus enem beliebigen Pfad den Dateinamen ermittelt. Der Namespace System.IO.Path bietet noch viele weitere Functionen im Bereich Pfade und URLs.

 

Nun wird ein Array vom Typ Byte deklariert ("FileContent

IOStream.Read ließt uns anschließend die Daten in das übergebene Array, der zweite Parameter enthält, ab welcher Position des Arrays die Daten eingefügt werden sollen und der Dritte, die Länge der Daten:

zweite Parameter enthält, ab welcher Position des Arrays die Daten eingefügt werden sollen und der Dritte, die Länge der Daten:

Dim fs As System.IO.FileStream

Dim FileContent(ContentLength) As Byte 
Dim status As Integer

' Datei ins ByteArray schreiben, geschriebene Daten erhalten:
status = IOStream.Read(FileContent, 0, ContentLength)

Die Funktion Read() gibt uns die Länge des Streams wieder, wenn also nichts empfangen wurde, erhalten wir 0, was uns hilft die weitere Verarbeitung zu überspringen, um fehler zu vermeiden, falls keine Dat

Wenn also eine Datei im Stream enthalten ist, ist der Status auf jeden Fall größer als 0 und wir können mit der Verarbeitung fortfahren und unseren Dateienzähler "Counter"; um eins erhöhen.

ist der Status auf jeden Fall größer als 0 und wir können mit der Verarbeitung fortfahren und unseren Dateienzähler "Counter"; um eins erhöhen.

 

Jetzt können wir die Daten die in unserem ByteArray enthalten sind in unser verzeichnis schreiben:

' Datei erzeugen
fs = System.IO.File.Create(Server.MapPath("files/") & FileName, _
        ContentLength)
' Daten in Datei schreiben, wenn möglich
If fs.CanWrite Then fs.Write(FileContent, 0, ContentLength)
' Schreibe-Puffer leeren
fs.Flush()
' FileStream zerstören
fs.Close()