Správce souborů pomocí DataGridu v ASP.NET – upload souborů
Pomocí vykazovacích prvků DataGrid nebo Datalist můžeme snadno dát uživatelům k dispozici webové rozhraní pro soubory na serveru. V tomto článku si ukážeme, jak obsluhovat události v Datagridu, jak jeho prostřednictvím nahrávat nové soubory na server a jak stávající soubory přejmenovávat.
Na DataGrid máme navázany obsluhy různých událostí, což je důležité, pokud po DataGridu chceme více než jen prosté vysypání dat do stránky (v takovém případě by se navíc mnohem lépe hodil Repeater). Následují tedy metody zajišťující stránkování DataGridPage(), změnu počtu řádků SetPageSize(), nastavení výrazu pro vyhledávání SearchDataGrid(), přepnutí do editačního režimu DataGridEdit() a jeho stornování DataGridCancel(), zpracování příkazů (uložení, smazání) DataGridCommand() a také doplnění výsledné tabulky o změnu barvy řádku při přejetí myší obslužnou metodou DataGridItemDataBound().
Většina těchto metod neprovádí nic světoborného, víceméně tvoří „bižuterii“ – aby nám například DataGrid nezůstával přepnutý do editačního režimu nebo aby nedošlo k chybě, pokud bude třeba uživatel na stránce 30 a náhle zvýší počet řádků natolik, že se data vejdou na 10 stránek. Pokud bychom při změně velikosti stránky nenastavili aktuální stránku CurrentPageIndex na 0, dozajista by při popisované situaci došlo k výjimce.
void SetPageSize(Object sender, EventArgs e)
{
Datagrid1.EditItemIndex = -1;
Datagrid1.ShowFooter = true;
Datagrid1.CurrentPageIndex = 0;
BindDataGrid();
}
void DataGridPage (Object sender, DataGridPageChangedEventArgs e)
{
Datagrid1.EditItemIndex = -1;
Datagrid1.ShowFooter = true;
Datagrid1.CurrentPageIndex = e.NewPageIndex;
BindDataGrid();
}
void SearchDataGrid(object sender, CommandEventArgs e)
{
switch(e.CommandName)
{
case „all“:
txbSearch.Text = String.Empty;
ViewState[„CharArgument“] = null;
break;
case „phrase“:
ViewState[„CharArgument“] = null;
break;
case „char“:
ViewState[„CharArgument“] = (String)e.CommandArgument;
txbSearch.Text = String.Empty;
break;
default:
break;
}
Datagrid1.EditItemIndex = -1;
Datagrid1.ShowFooter = true;
Datagrid1.CurrentPageIndex = 0;
BindDataGrid();
}
void DataGridItemDataBound(Object sender, DataGridItemEventArgs e)
{
if (e.Item.ItemType == ListItemType.Item)
{
e.Item.Attributes.Add(„onmouseover“, „javascript: this.style.backgroundColor=’#FFDDE7′;“);
e.Item.Attributes.Add(„onmouseout“, „javascript: this.style.backgroundColor=’#FFFFFF‘;“);
}
if (e.Item.ItemType == ListItemType.AlternatingItem)
{
e.Item.Attributes.Add(„onmouseover“, „javascript: this.style.backgroundColor=’#FFDDE7′;“);
e.Item.Attributes.Add(„onmouseout“, „javascript: this.style.backgroundColor=’#E7E7E7′;“);
}
}
void DataGridEdit(Object sender, DataGridCommandEventArgs e)
{
Datagrid1.EditItemIndex = e.Item.ItemIndex;
Datagrid1.ShowFooter = false;
BindDataGrid();
}
void DataGridCancel(Object sender, DataGridCommandEventArgs e)
{
Datagrid1.EditItemIndex = -1;
Datagrid1.ShowFooter = true;
BindDataGrid();
}
void DataGridCommand(Object sender, DataGridCommandEventArgs e)
{
// přetypujeme předanou hodnotu argumentu e.CommandSource na LinkButton a rozhodneme podle vlastnosti CommandName
switch(((LinkButton)e.CommandSource).CommandName)
{
case „Delete“:
ItemDelete(e);
break;
case „Insert“:
ItemInsert(e);
break;
default:
break;
}
}
Výše uvedené metody, myslím, nevyžadují detailní popis, vše by mělo být jasné z kódu. Za zmínku snad stojí rozhodnutí o prováděném povelu pomocí switch-case, kde požadovaný povel získáme přetypováním vlastnosti CommandSource vstupního parametru typu DataGridCommandEventArgs.
Smazání záznamu provede metoda ItemDelete():
void ItemDelete(DataGridCommandEventArgs e)
{
// ošetřit výjimky
try
{
// cesta a jméno souboru z kolekce DataKeys
String myMediaPath = xmlDirectory + Datagrid1.DataKeys[e.Item.ItemIndex];
// pokud soubor existuje, provést smazání metodou Delete() a zneviditelnit chybové hlášení
if (File.Exists(myMediaPath))
{ // pokud
File.Delete(myMediaPath);
lblError.Visible = false;
}
// soubor neexistuje nebo k zadané cestě není přístup, zviditelníme hlášení
else
lblError.Visible = true;
}
// došlo k nějaké chybě, zviditelníme hlášení
catch
{
lblError.Visible = true;
}
lblError.Text = „Chyba při mazání souboru – soubor již možná neexistuje…“;
// pokud není chybové hlášení viditelné, nedošlo k chybě – nastavíme DataGrid do „základního“ nastavení a naplníme čerstvými daty
if (!lblError.Visible)
{
Datagrid1.EditItemIndex = -1;
Datagrid1.CurrentPageIndex = 0;
Datagrid1.ShowFooter = true;
BindDataGrid();
}
}
Velmi podobná je metoda zajišťující přejmenování souboru, v níž navíc musíme vyřešit získání hodnoty textového pole, které není jednoduše přístupné, protože je skryto uvnitř šablony DataGridu. Vzniká totiž za běhu a to pouze tehdy, je-li DataGrid, respektive některý jeho řádek, v editačním režimu – jinak vůbec neexistuje. Pro dohledání prvku bychom mohli použít metodu FindControl(), ale zde můžeme prvek i „dopočítat“, což je rychlejší. Pokud by někdo raději použil FindControl(), může postupovat obdobně jako u níže popsané metody pro přidávání nových záznamů, kde jsou prvky v šabloně zápatí.
void DataGridUpdate(Object sender, DataGridCommandEventArgs e)
{
// provedeme jen když neprotestují validátory
if (Page.IsValid)
{
// ošetřit výjimky
try
{
// získat přístup k objektu textového pole v šabloně – přetypujeme objekt v daném sloupci (buňce)
TextBox txtFileName = (TextBox) e.Item.Cells[0].Controls[1];
// pokud není zadané jméno souboru odlišné od stávajího, nebudeme přejmenování provádět
if (txtFileName.Text != Datagrid1.DataKeys[e.Item.ItemIndex])
// metodou Move() přesuneme/přejmenujeme soubor do nového místa (na nový název)
File.Move(xmlDirectory+Datagrid1.DataKeys[e.Item.ItemIndex],xmlDirectory+txtFileName.Text);
// skryjeme chybové hlášení
lblError.Visible = false;
}
catch (Exception eX)
{
// došlo k nějaké chybě, nastavíme text hlášení a zviditelníme je
lblError.Text = „Soubor se nezdařilo přejmenovat, možná je používán jinou aplikací…<br />“+eX.ToString();
lblError.Visible = true;
}
}
// pokud není chybové hlášení viditelné, nedošlo k chybě – nastavíme DataGrid do „základního“ nastavení a naplníme čerstvými daty
if (!lblError.Visible)
{
Datagrid1.EditItemIndex = -1;
Datagrid1.ShowFooter = true;
BindDataGrid();
}
}
Na závěr jsem si nechal nejdůležitější metodu – ta zajišťuje upload souboru od klienta na server.
void ItemInsert(DataGridCommandEventArgs e)
{
// provedeme jen když neprotestují validátory
if (Page.IsValid)
{
// ošetříme výjimky
try
{
// v šabloně dohledáme HtmlInputFile přetypováním dohledaného prvku v kolekci Item předaného parametru typu DataGridCommandEventArgs
HtmlInputFile myFile = (HtmlInputFile) e.Item.FindControl(„myFile“);
// provedeme pouze pokud je nějaký soubor zadaný a byl doručen nenulový obsah
if (myFile.PostedFile != null && myFile.PostedFile.ContentLength > 0 )
{
// původní jméno souboru s cestou
String fname = myFile.PostedFile.FileName;
// uložit do zadané cesty s původním názvem (původní cestu odřízneme)
myFile.PostedFile.SaveAs(xmlDirectory + fname.Substring(fname.LastIndexOf(„\\“)+1));
// skrýt chybové hlášení
lblError.Visible = false;
}
else
{
// soubor na server nedorazil, nebo má nulovou délku, zviditelníme hlášení
lblError.Visible = true;
lblError.Text = „Soubor nebyl zadán nebo není správného typu.<br />“;
}
}
catch (Exception eX)
{
// došlo k nějaké chybě, zviditelníme hlášení
lblError.Visible = true;
lblError.Text = „Došlo k chybě při ukládání dat…<br />“;
}
}
// pokud není chybové hlášení viditelné, nedošlo k chybě – nastavíme DataGrid do „základního“ nastavení a naplníme čerstvými daty
if (!lblError.Visible)
{
Datagrid1.EditItemIndex = -1;
Datagrid1.ShowFooter = true;
BindDataGrid();
}
}
Zde chci jen připomenout statickou hodnotu ValidFileExpression z předchozího článku, která připravuje řetězec regulárního výrazu pro validátory v DataGridu. V šabloně máme použity dva, jeden v editační šabloně a jeden v zápatí. Hodnotu ValidationExpression zde bindujeme výrazem ValidationExpression='<%# ValidFileExpression %>‘, u validátoru v zápatí si také všimněte bindování povolení validátoru v závislosti na viditelnosti zápatí Enabled='<%# Datagrid1.ShowFooter %>‘. Pokud by validátor (zejména RequiredFieldValidator) v zápatí zůstal povolen, bylo by problematické uložit údaje z editační šablony – validátory by zde protestovaly kvůli polím v zápatí, které nás však při editaci vůbec nezajímají. Po ukončení editace je zápatí opět zviditelněno a tím se povolí i validátory v něm definované.
Pro zobrazení rozměrů obrázků nám poslouží metody IsImage() a ImageSize(). První metoda nám poslouží také k vygenerování odkazu pro náhled obrázku při přejetí myší – zde v závislosti na tom, zda jde o obrázek, generujeme odlišné hodnoty atributů onmouseout a onmouseover metodou LinkPreview().
Boolean IsImage(String fileName)
{
// v zadaném řetězci najdeme pozici poslední tečky
Int32 myExtIndex = fileName.LastIndexOf(„.“);
if (myExtIndex > -1)
{
// pokud byla tečka nalezena, vyjmeme část řetězce od tečky do konce převedenou na malé znaky jako příponu
String myExtension = fileName.Substring(myExtIndex+1).ToLower();
if (myExtension == „jpg“ || myExtension == „jpeg“ || myExtension == „gif“ || myExtension == „gif“ || myExtension == „png“ || myExtension == „tif“ || myExtension == „bmp“ || myExtension == „ico“)
// pokud se přípona rovná některé z vyjmenovaných, jde o obrázek
return true;
else
// jinak jde o soubor jiného typu
return false;
}
else
// zadané jméno souboru neobsahuje tečku, je bez přípony, není to obrázek
return false;
}
String ImageSize(String fileName)
{
if (IsImage(fileName))
{
System.Drawing.Bitmap objBMP;
objBMP = new Bitmap(xmlDirectory + fileName, false);
try
{
return “ (“ + objBMP.Width.ToString() + „x“ + objBMP.Height.ToString() + „)“;
}
catch
{
return string.Empty;
}
}
else
return String.Empty;
}
Starší komentáře ke článku
Pokud máte zájem o starší komentáře k tomuto článku, naleznete je zde.
Mohlo by vás také zajímat
-
Jak zabezpečit váš chytrý telefon před kybernetickými hrozbami
30. listopadu 2023 -
inPage AI: Jak na generování obsahu
18. července 2024
Nejnovější
-
Výkonný a kompaktní: ASOME Max Studio s výjimečným poměrem cena/výkon
11. listopadu 2024 -
Šokující data od Microsoftu: Kyberútoky rostou o stovky procent!
8. listopadu 2024 -
Chcete jedinečnou doménu? Objevte koncovky FOOD, MEME a MUSIC!
7. listopadu 2024 -
OpenAI představilo novou funkci ChatGPT Search
6. listopadu 2024