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()