Vícenásobný upload souborů na server pomocí prohlížeče v ASP.NET

5. února 2003

Potřebujete nahrát na web server přes web rozhraní více souborů najednou ? V dnešním článku se dozvíte hned o několika způsobech jak takovýto upload realizovat.

V předešlém článku o uploadu souborů na server jste si měli možnost vytvořit web stránku pro upload jednoho souboru. Pokud však budete chtít vybrat a na server odeslat najednou více souborů, nastávají problémy. Ovládací prvek file totiž takovouto možnost nepodporuje.

Pokud se již teď chytáte za hlavu, že tuto funkčnost potřebujete, můžete zůstat klidní, stačí jen trochu práce a půjde to dokonce i více způsoby, jak už jsem předeslal v úvodu.

Většinu z vás pravděpodobně napadne nakopírovat do stránky několik ovládacích prvků file a ty následně společně ošetřit. Řešení to sice je, ale poněkud náročné na čas a úpravy kódu, vzhledem k tomu, že již při tvorbě aplikace pevně definujeme počet souborů pro upload. Nicméně pustíme se do tohoto řešení a následně si ukážeme jak jej vylepšit.

Vezmeme tedy příklad z minulého článku a ovládací prvek file, který se v příkladu jmenuje „Soubor“ umístíme do stránky hned 3x a nazveme jej Soubor1, Soubor2, Soubor3. V příkladu jsme používali i ovládací prvek Label, který se jmenoval Status. I s tímto prvkem provedeme totéž a nazveme jej Status1, Status2, Status3. Zdrojový kód formuláře pak bude vypadat zhruba takto:

<%@ Page language=“c#“ Codebehind=“default.aspx.cs“ AutoEventWireup=“false“ Inherits=“upload.WebForm1″ %>
<!doctype html public „-//W3C//DTD HTML 4.0 Transitional//EN“ >
<html>
   <head>
      <title>Upload souboru na server</title>
      <meta content=“Microsoft Visual Studio 7.0″ name=“GENERATOR“>
      <meta content=“C#“ name=“CODE_LANGUAGE“>
      <meta content=“JavaScript“ name=“vs_defaultClientScript“>
      <meta content=“http://schemas.microsoft.com/intellisense/ie5″ name=“vs_targetSchema“>
   </head>
   <body MS_POSITIONING=“GridLayout“>
      <form id=“Form1″ method=“post“ encType=“multipart/form-data“ runat=“server“>
         <INPUT id=“Soubor1″ style=“Z-INDEX: 101; LEFT: 14px; POSITION: absolute; TOP: 17px“ type=“file“ runat=“server“ NAME=“Soubor1″>
         <INPUT id=“Soubor2″ style=“Z-INDEX: 104; LEFT: 13px; POSITION: absolute; TOP: 41px“ type=“file“ name=“File1″ runat=“server“>
         <INPUT id=“Soubor3″ style=“Z-INDEX: 105; LEFT: 14px; POSITION: absolute; TOP: 65px“ type=“file“ name=“File2″ runat=“server“>
         <asp:Label id=“Status1″ style=“Z-INDEX: 107; LEFT: 18px; POSITION: absolute; TOP: 100px“ runat=“server“ Width=“376px“ Height=“90px“></asp:Label>
         <asp:Label id=“Status2″ style=“Z-INDEX: 103; LEFT: 18px; POSITION: absolute; TOP: 196px“ runat=“server“ Height=“90px“ Width=“376px“></asp:Label>
         <asp:Label id=“Status3″ style=“Z-INDEX: 106; LEFT: 20px; POSITION: absolute; TOP: 296px“ runat=“server“ Width=“376px“ Height=“90px“></asp:Label>
         <asp:button id=“uloz_soubor“ style=“Z-INDEX: 100; LEFT: 272px; POSITION: absolute; TOP: 17px“ runat=“server“ Text=“Ulož na server“></asp:button>
      </form>
   </body>
</html>

Zbývá ještě doplnit akce při kliknutí na tlačítko. To provedete tak, že pouze překopírujete kód z příkladu v minulém článku a změníte indexy u prvku Soubor a Status. Kód prováděný při stisku tlačítka bude po úpravách vypadat takto:

private void uloz_soubor_Click(object sender, System.EventArgs e)
{
   if (Soubor1.PostedFile != null) // pokud neni vytvoren proud dat nelze nic delat
   {
      if (Soubor1.PostedFile.ContentLength>0) // je velikost souboru vetsi nez nula ?
      {
         try // zkusime tedy soubor ulozit
         {
            string strFileNamePath = Soubor1.PostedFile.FileName;
            int intPoziceZacatkuJmena = strFileNamePath.LastIndexOf(„\\“)+1;
            string strFileNameOnly=strFileNamePath.Remove(0,intPoziceZacatkuJmena);
            Soubor1.PostedFile.SaveAs(Server.MapPath(„dta/“)+strFileNameOnly);
            Status1.Text = „Soubor uspěšně uložen na server <br> Velikost souboru:“+Soubor1.PostedFile.ContentLength+“<br>Zdrojová cesta: „+strFileNameOnly;
            Status1.ForeColor=System.Drawing.Color.Green;
         }
         catch (Exception exc) // ulozeni se nezdarilo – zpracujeme vyjimku
         {
            Status1.Text = „Chyba při ukládání“ + exc.ToString();
            Status1.ForeColor=System.Drawing.Color.Red;
         }
      }
      else // velikost souboru je nulova – neni co ukladat
      {
         Status1.Text = „Není co ukládat“;
         Status1.ForeColor=System.Drawing.Color.Red;
      }
   }
   if (Soubor2.PostedFile != null) // pokud neni vytvoren proud dat nelze nic delat
      {
         if (Soubor2.PostedFile.ContentLength>0) // je velikost souboru vetsi nez nula ?
         {
            try // zkusime tedy soubor ulozit
            {
               string strFileNamePath = Soubor1.PostedFile.FileName;
               int intPoziceZacatkuJmena = strFileNamePath.LastIndexOf(„\\“)+1;
               string strFileNameOnly=strFileNamePath.Remove(0,intPoziceZacatkuJmena);
               Soubor2.PostedFile.SaveAs(Server.MapPath(„dta/“)+strFileNameOnly);
Status2.Text = „Soubor uspěšně uložen na server <br> Velikost souboru:“+Soubor2.PostedFile.ContentLength+“<br>Zdrojová cesta: „+strFileNameOnly;
               Status2.ForeColor=System.Drawing.Color.Green;
            }
            catch (Exception exc) // ulozeni se nezdarilo – zpracujeme vyjimku
            {
               Status2.Text = „Chyba při ukládání“ + exc.ToString();
               Status2.ForeColor=System.Drawing.Color.Red;
            }
         }
         else // velikost souboru je nulova – neni co ukladat
         {
            Status2.Text = „Není co ukládat“;
            Status2.ForeColor=System.Drawing.Color.Red;
         }
      }
   if (Soubor3.PostedFile != null) // pokud neni vytvoren proud dat nelze nic delat
   {
      if (Soubor3.PostedFile.ContentLength>0) // je velikost souboru vetsi nez nula ?
      {
         try // zkusime tedy soubor ulozit
         {
            string strFileNamePath = Soubor3.PostedFile.FileName;
            int intPoziceZacatkuJmena = strFileNamePath.LastIndexOf(„\\“)+1;
            string strFileNameOnly=strFileNamePath.Remove(0,intPoziceZacatkuJmena);
            Soubor3.PostedFile.SaveAs(Server.MapPath(„dta/“)+strFileNameOnly);
            Status3.Text = „Soubor uspěšně uložen na server <br> Velikost souboru:“+Soubor3.PostedFile.ContentLength+“<br>Zdrojová cesta: „+strFileNameOnly;
            Status3.ForeColor=System.Drawing.Color.Green;
         }
         catch (Exception exc) // ulozeni se nezdarilo – zpracujeme vyjimku
         {
            Status3.Text = „Chyba při ukládání“ + exc.ToString();
            Status3.ForeColor=System.Drawing.Color.Red;
         }
      }
      else // velikost souboru je nulova – neni co ukladat
      {
         Status3.Text = „Není co ukládat“;
         Status3.ForeColor=System.Drawing.Color.Red;
      }
   }
}

Jistě si dovede představit tu šílenou práci, pokud budete chtít na server uploadovat více než 3 soubory současně. Nicméně si můžete stáhnout zdrojové kódy. Doufám však, že toto budete brát spíše jako ukázku jak podobnou věc nedělat, než jako návod k provádění téhož.

Nyní, když tedy víme, jak problém neřešit, pokusíme se najít řešení jiné. Kód aspx stránky zůstane téměř stejný, ovšem s tím rozdílem, že nám bude stačit jeden prvek Label pro výpis stavu ukládání. Pro získání reference na soubory určené pro upload použijeme vlastnost Files třídy HttpRequest, která nám poskytne kolekci, v níž jsou obsaženy reference na soubory, které se mají uploadovat na server.

Nyní stačí pouze cyklem projít tuto kolekci a pomocí třídy HttpPostedFile zpracovat jednotlivé soubory stejným způsobem jako v předchozím případě.

private void uloz_soubor_Click(object sender, System.EventArgs e)
{
   string strMessage=““;
   HttpPostedFile ObjSoubor;
   for (int i=0;i< Request.Files.Count;i++) // cykl přes prvky kolekce Files
   {
      ObjSoubor=Request.Files[i]; // ziskani reference na jeden soubor
      if (ObjSoubor.ContentLength>0) // máme co uložit, pokračujeme dále
      {
         string strFileNamePath = ObjSoubor.FileName;
         int intPoziceZacatkuJmena = strFileNamePath.LastIndexOf(„\\“)+1;
         string strFileNameOnly=strFileNamePath.Remove(0,intPoziceZacatkuJmena);
         try // zkusime uložit
         {
            ObjSoubor.SaveAs(Server.MapPath(„dta/“)+strFileNameOnly);
            strMessage=strMessage+“Soubor „+strFileNameOnly+“ uložen na server<br>“;
         }
         catch (Exception exc) // ulozeni se nezdarilo – zpracujeme vyjimku
         {
            strMessage=strMessage+“Soubor „+strFileNameOnly+“ nelze uložit<br>“;
         }
         Status.Text=strMessage; // vypíšeme výsledek operace.
      }
   }
}

No řekněte sami, není takovýto kód přehlednější? Určite ano. Mnozí z vás ale namítnou, že opět bude nutné při změně požadovaného počtu souboru nutné modifikovat kód. Ano je to pravda, ale modifikovat budete pouze vzhled (tedy soubor aspx) a nikoliv programový kód, který je přeložen.

Kompletní zdrojové kódy si můžete opět stáhnout.

Ovšem ani toto řešení není ideální a staví uživatele do situace, ve které je před něj postavena možnost nahrát na server najednou maximálně x souborů a tím ho omezuje. V příštím článku na toto téma se tedy můžete těšit na řešení, které umožní uživateli připravit „neomezeně velký“ seznam souborů a ten jediným kliknutím odeslat na server.

Starší komentáře ke článku

Pokud máte zájem o starší komentáře k tomuto článku, naleznete je zde.

Předchozí článek redboss.cz
Štítky: Články

Mohlo by vás také zajímat

Nejnovější

Napsat komentář

Vaše e-mailová adresa nebude zveřejněna. Vyžadované informace jsou označeny *