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

Online File Management System mit ASP.NET und C# - Teil 2

Geschrieben von: Rudolf Ball
Kategorie: ASP.NET

This printed page brought to you by AlphaSierraPapa

Es gibt eine komfortable Möglichkeit, seine Daten, Dateien und Verzeichnisse online zu verwalten: ein Online File Management System (OFMS). Im ersten Teil der Artikelserie haben wir uns damit beschäftigt, Dateien und Verzeichnisse online browsebar zu machen. Heute implementieren wir die Funktionen für Upload und Download (Sektion "Bestandsveränderungen"), sowie das Editieren von Textdateien - mehr dazu in der Sektion "Facelifting".

Bestandsveränderungen

Als nächsten Schritt wollen wir den Dateidownload als auch den Upload implementieren. Der Dateidownload ist einfach, wir benötigen dazu nur eine weitere Spalte in unserer DateienUndVerzeichnisse Tabelle, in welche wir das Symbol

einfügen. Der extra benötigte Code in der Funktion TabelleDateienUndVerzeichnisseFuellen sieht folgendermaßen aus:

...
ZelleDownload = new TableCell();
LinkDownload = new HyperLink();
...
LinkDownload.Text = "<img src=\"./Bilder/Download.gif\" border=\"0\" height=\"16\" width=\"16\"" + 
                           "Alt=\"Datei herunterladen\">";
LinkDownload.NavigateUrl = "Download.aspx?Dateiname=" + Ort;
ZelleDownload.Controls.Add(LinkDownload);
...
Zeile.Cells.Add(ZelleDownload);
...

Wie man sieht linken wir auf einen neuen WebForm namens Download.aspx. Diese WebForm besitzt kein User Interface sondern besteht nur aus einem PageLoad Event, welches ich im Folgenden besprechen möchte.

string Dateiname = Server.MapPath(Request.Params["Dateiname"]);
System.IO.FileInfo Datei = new System.IO.FileInfo(Dateiname);
Response.Clear();
Response.AddHeader("Content-Disposition","attachment; filename=" + Datei.Name);
Response.AddHeader("Content-Length",Datei.Length.ToString());
Response.ContentType = "application/octet-stream";
Response.WriteFile(Datei.FullName);
Response.End();

Die Variable Dateiname wird mit dem Wert des Parameters Dateiname des Querystrings gefüllt. Ein FileInfo namens Datei beschreibt diese. Mit dem Aufruf Response.Clear löschen wir den Puffer (falls bereits etwas geschrieben sein sollte). Um einen "Speichern unter" Dialog erzeugen zu können müssen wir einen zusätzlichen Header einfügen, und diesem Header weisen wir den gewünschten Dateinamen zu. Als nächsten Schritt weisen wir dem Header Content-Length die Dateigröße zu, denn damit ist gewährleistet, daß der Benutzer eine Fortschrittsanzeige angezeigt bekommen. Mit dem ContentType "application/octet-stream" definieren wir, daß es sich um einen Stream handelt, welcher vom Client nur heruntergeladen werden kann (und eben nicht geöffnet). Anschließend senden wir den Stream zum Client. Response.End beendet die Ausführung dieser Seite.

Somit wird durch einen Klick auf das Download-Image zur Downloadseite gelinkt (Download.aspx) und der Dateinname im Querystring übergeben. Die Datei wird als Stream zum Client gesendet. Ganz anders sieht der Vorgang jedoch beim Upload aus.

Für den Upload haben wir auf die Hauptseite (OFMS.aspx) ein HTML Input Control gesetzt, welches wir jedoch mit dem runat=server Attribut vesehen haben, um auf die Daten zugreifen zu können. Der eingefügte HTML Code sieht wie folgt aus.

<tr bgColor="khaki">
   <td width="100"><font face="Verdana" color="black" size="1"><b>Datei Upload </b></font>
   </td>
   <td width="200">
      <input id="DateiUpload" runat="server" type="file" name="DateiUpload" width="100%">
   </td>
   <td width="500">
      <asp:Button Runat="server" ID="Upload" Text="Upload"></asp:Button>
   </td>
</tr>

Wie wir sehen, haben wir ein Inputfeld DateiUpload vom Typ "file" eingefügt. Automatisch wird hier eine Textbox und ein "Browse" Button angezeigt, welcher bei Klick einen Dialog zur Dateiauswahl öffnet. Weiters benötigen wir einen Button "Upload", welcher die zuvor selektierte Datei endgültig in unser Web befördert. Der Click-Event des Buttons Upload sieht wie folgt aus.

private void DateiUpload_Click(object sender, System.EventArgs e)
{
   string aktuellesVerzeichnis = Request.Params["Verzeichnis"];
   if (aktuellesVerzeichnis == null || aktuellesVerzeichnis.Length == 0)
   {
      aktuellesVerzeichnis = Request.ApplicationPath.ToString();
   }
   if (DateiUpload.PostedFile != null && DateiUpload.PostedFile.FileName.Length > 0)
   {
      string Zielverzeichnis = Server.MapPath(aktuellesVerzeichnis);
      try
      {
         string Dateiname = Path.GetFileName(DateiUpload.PostedFile.FileName);
         DateiUpload.PostedFile.SaveAs(Path.Combine(Zielverzeichnis,Dateiname));
         Response.Redirect("OFMS.aspx?Verzeichnis=" + aktuellesVerzeichnis);
      }
      catch(Exception ex)
      {
         StatusMessage.Text = ex.Message;
         StatusMessage.Visible = true;
      }
   }
}

Interessant ist hier, daß wir auf die selektierte Datei durch DateiUpload.PostedFile zugreifen können. Somit können wir die Datei mit DateiUpload.PostedFile.Save einfach in unserem Zielverzeichnis speichern. Anschließend führt uns ein Response.Redirect wieder auf die Hauptseite OFMS.aspx zurück, natürlich ins richtige Verzeichnis. Somit sehen wir, daß weder der Up- noch der Download von Dateien mit ASP.NET ein Problem darstellt. Im Browser sieht das Ganze dann so aus.

Beim Klick auf "Browse" öffnet sich der Dialog "Datei öffnen ...". Anschließend steht der Dateipfad in der Textbox. Erst durch den Klick auf den "Upload"-Button wird die Datei hochgeladen.

Facelifting

Was hilft es uns, die Dateien online aufzulisten, wenn wir sie weder einsehen noch bearbeiten können. Aus diesem Grund möchten wir mit unserem OFMS dem Benutzer diese Möglichkeit einräumen. Wir benötigen hierfür zwei Komponenten. Einerseits eine WebForm zum Editieren (Editor.aspx) und andererseits einen Edit-Button

mit Link auf die Editorseite von unserer Hauptseite aus. Der Code für den Link ist einfach und unterscheidet sich nur geringfügig von dem des Download-Buttons.

LinkEdit.Text = "<img src=\"./Bilder/Editor.gif\" border=\"0\" height=\"16\" _
		width=\"16\" Alt=\"Datei editieren\">";
LinkEdit.NavigateUrl = "Editor.aspx?Dateiname=" + Ort;
ZelleEdit.Controls.Add(LinkEdit);

Dem zuvor erzeugten Hyperlink LinkEdit wird als Text ein Image-Tag hinzugefügt (Editor.gif). Als Ziel (NavigateUrl) wird die Editor.aspx Seite angegeben, jedoch mit dem Pfad der zu editierenden Datei (Ort) als Parameter. Anschließend wird der Hyperlink der Zelle ZelleEdit hinzugefügt. Dies war der einfache Teil.

Auf die Editor.aspx Seite gelinkt wird sogleich das PageLoad-Event ausgeführt. Dieses Event sieht wie folgt aus:

private void Page_Load(object sender, System.EventArgs e)
{
if (!Page.IsPostBack)
{
   string Dateipfad = Request.Params["Dateiname"];
   if (Dateipfad != null)
   {
      if (Request.Params["erzeugen"] == null || Request.Params["erzeugen"] == "false")
      {
         try
         {
           StreamReader sr = new StreamReader(File.Open(Server.MapPath(Dateipfad),FileMode.Open));
           DateiInhalt.Text = sr.ReadToEnd();
           sr.Close();
         }
         catch (Exception ex)
         {
           StatusMessage.Text = ex.Message;
           StatusMessage.Visible = true;
         }
      }
   DateiSpeichernUnter.Text = Dateipfad;
   }
}
}

Der Variable Dateipfad wird der Dateiname, welcher durch den Querystring übergeben wurde, zugewiesen. Weiters wird der Parameter "erzeugen" abgefragt, denn sollte dieser übersprungen werden wollen wir eine neue Datei erzeugen und benötigen nicht das Hochladen und Anzeigen einer anderen. Anschließend öffnen wir einen neuen StreamReader, welchem wir als Eingabeparameter die offenen Datei übergeben. Der auf der Editor.aspx - Seite definierten Textbox DateiInhalt weisen wir den StreamReader zu, welcher sie füllt. Somit zeigen wir den Inhalt (=Text) der Datei in der Textbox an. Zu guter letzt wird in die Textbox DateiSpeichernUnter der Dateipfad eingetragen, was ein Speichern bei Veränderung auch unter einem anderen Name erlaubt.

Schlußendlich möchten wir noch die Datei nach eventuellen Änderungen speichern. Das Click-Event hierfür sieht folgendermaßen aus:

private void DateiSpeichern_Click(object sender, System.EventArgs e)
{
   try
   {
      string DateiPfad = DateiSpeichernUnter.Text;
      if (!DateiPfad.StartsWith("/"))
      {
         DateiPfad = "/" + DateiPfad;
      }
      StreamWriter DateiStreamWriter = File.CreateText(Server.MapPath(DateiPfad));
      DateiStreamWriter.Write(DateiInhalt.Text);
      DateiStreamWriter.Close();
      StatusMessage.Text = "Datei wurde erfolgreich gespeichert!";
   }
   catch (Exception ex)
   {
      StatusMessage.Text = ex.Message;
   }
   StatusMessage.Visible = true;
}

Hierfür prüfen wir den noch virtuellen Dateipfad auf syntaktische Gültigkeit und mappen ihn, damit wir ihn physisch erhalten. Anschließend erzeugen wir einen StreamWriter, in welchen wir den Inhalt unserer Textbox DateiInhalt schreiben. Nachdem wir den StreamWriter geschlossen haben geben wir noch eine Erfolgsmeldung aus. In diesem Codebeispiel sehen wir sehr schön, daß das Speichern von Dateien aus dem Webbrowser heraus keinerlei Problem darstellt. Der folgende Screenshot zeigt, wie die Datei web.config im OFMS-Editor dargestellt wird.

Schlußbemerkung

Ein Online File Management System zu entwickeln hat mir sehr viel Spaß bereitet. Dieses nützliche Tool ist jedoch noch nicht reif, eine ganze Reihe von Zusatzfunktionen sind möglich und wären wünschenswert. Ich denke da nur an die Möglichkeit von Kopier-, Ausschneid- und Move-Funktionen, das Erstellen von Verzeichnissen (dem der Dateien sehr ähnlich), die Kontrollabfragen bei Löschen ("Wollen Sie wirklich ...") etc.

Und auf einen wichtigen Punkt haben wir überhaupt keine Rücksicht genommen, und zwar auf Datensicherheit. Es wäre ein zu großes Risiko, diese Funktionalität ohne Zugriffssicherung ins Web zu stellen. Aus diesem Grund wäre eine Form der Authentifizierung denkbar und notwendig. Ansonsten ist die Entwicklung solch eines Systems mit ASP.NET und dem .NET Framework recht einfach, da alle notwendigen Funktionen vorhanden und leicht verständlich verwendbar sind.

This printed page brought to you by AlphaSierraPapa

Download des Codes

Klicken Sie hier, um den Download zu starten.
http://www.aspheute.com/code/20021105.zip

Verwandte Artikel

Dateien lesen in ASP.NET
http:/www.aspheute.com/artikel/20000929.htm
Dateien umbenennen
http:/www.aspheute.com/artikel/20020409.htm
Directory Browsing a la .NET
http:/www.aspheute.com/artikel/20000804.htm
Ein Touch-Utility in C#
http:/www.aspheute.com/artikel/20020226.htm
Online File Management System mit ASP.NET und C# - Teil 1
http:/www.aspheute.com/artikel/20021031.htm
Web-basiertes Dateimanagement mit dem ASP FileMan
http:/www.aspheute.com/artikel/20010507.htm

Links zu anderen Sites

Are you sure you want to delete that?
http://aspalliance.com/aldotnet/examples/cd.aspx
Dynamic Controls in ASP.NET
http://aspnet.4guysfromrolla.com/articles/081402-1.aspx
TextReader and TextWriter In C#
http://www.csharphelp.com/archives/archive147.html

 

©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.