Zobrazení binárních dat ve webových ovládacích prvcích dat (C#)
V tomto kurzu se podíváme na možnosti prezentace binárních dat na webové stránce, včetně zobrazení souboru obrázku a zřízení odkazu Stáhnout pro soubor PDF.
Úvod
V předchozím kurzu jsme prozkoumali dvě techniky přidružení binárních dat k podkladovému datovému modelu aplikace a použili jsme ovládací prvek FileUpload k nahrání souborů z prohlížeče do systému souborů webového serveru. Zatím jsme zjistili, jak nahraná binární data přidružit k datovému modelu. To znamená, že po nahrání a uložení souboru do systému souborů musí být cesta k souboru uložena v příslušném záznamu databáze. Pokud jsou data uložena přímo v databázi, nemusí být nahraná binární data uložena do systému souborů, ale musí být vložena do databáze.
Než se ale podíváme na přidružení dat k datovému modelu, podívejme se nejprve na to, jak poskytnout binární data koncovému uživateli. Prezentace textových dat je dostatečně jednoduchá, ale jak by se měla prezentovat binární data? To samozřejmě závisí na typu binárních dat. U obrázků pravděpodobně chceme obrázek zobrazit; v případě souborů PDF, dokumentů Microsoft Word, souborů ZIP a dalších typů binárních dat je pravděpodobně vhodnější poskytnout odkaz Ke stažení.
V tomto kurzu se podíváme na to, jak prezentovat binární data spolu s přidruženými textovými daty pomocí webových ovládacích prvků dat, jako jsou GridView a DetailsView. V dalším kurzu se podíváme na přidružení nahraného souboru k databázi.
Krok 1: ZadáníBrochurePath
hodnot
Sloupec Picture
v tabulce Categories
již obsahuje binární data pro různé obrázky kategorií. Konkrétně Picture
sloupec pro každý záznam obsahuje binární obsah rastrového obrázku s nízkou kvalitou, 16 barev. Každý obrázek kategorie má šířku 172 pixelů a výšku 120 pixelů a spotřebuje přibližně 11 kB. A co víc, binární obsah ve Picture
sloupci obsahuje 78 bajtů OLE hlavičku, která musí být odstraněna před zobrazením obrázku. Tyto informace o hlavičce jsou k dispozici, protože databáze Northwind má své kořeny v Aplikaci Microsoft Access. V Accessu se binární data ukládají pomocí datového typu objektu OLE, který se přichytá k této hlavičce. Prozatím uvidíme, jak z těchto obrázků v nízké kvalitě odebrat záhlaví, aby se obrázek zobrazil. V dalším kurzu vytvoříme rozhraní pro aktualizaci sloupce kategorie Picture
a nahradíme tyto rastrové obrázky, které používají záhlaví OLE, ekvivalentními obrázky JPG bez zbytečných záhlaví OLE.
V předchozím kurzu jsme viděli, jak používat ovládací prvek FileUpload. Proto můžete pokračovat a přidat soubory brožur do systému souborů webového serveru. Tím se ale neaktualizuje BrochurePath
sloupec v tabulce Categories
. V dalším kurzu se dozvíme, jak toho dosáhnout, ale prozatím musíme hodnoty pro tento sloupec zadat ručně.
V tomto kurzu ke stažení najdete sedm souborů PDF brožury ve ~/Brochures
složce, jeden pro každou z kategorií s výjimkou Seafood. Záměrně jsem vynechal přidání brožury Seafood, která ilustruje, jak zpracovat scénáře, kdy ne všechny záznamy mají přidružená binární data. Pokud chcete tabulku aktualizovat Categories
pomocí těchto hodnot, klikněte pravým tlačítkem na uzel v Průzkumníku Categories
serveru a zvolte Zobrazit data tabulky. Pak zadejte virtuální cesty k souborům brožury pro každou kategorii, která obsahuje brožuru, jak je znázorněno na obrázku 1. Vzhledem k tomu, že neexistuje žádná brožura pro kategorii Mořské plody, ponechte hodnotu sloupce BrochurePath
jako NULL
.
Obrázek 1: Ruční zadání hodnot pro Categories
sloupec tabulky BrochurePath
(kliknutím zobrazíte obrázek v plné velikosti)
Krok 2: Poskytnutí odkazu ke stažení brožur v zobrazení GridView
BrochurePath
S hodnotami zadanými pro Categories
tabulku jsme připraveni vytvořit GridView, který uvádí každou kategorii spolu s odkazem ke stažení brožury kategorií. V kroku 4 rozšíříme toto zobrazení GridView tak, aby zobrazilo také obrázek kategorie.
Začněte přetažením objektu GridView ze sady nástrojů do Designer DisplayOrDownloadData.aspx
stránky ve BinaryData
složce. Nastavte GridView s ID
na Categories
a prostřednictvím inteligentní značky GridView s a zvolte jeho vazbu k novému zdroji dat. Konkrétně ho vytvořte vazbu na ObjectDataSource s názvem CategoriesDataSource
, který načítá data pomocí CategoriesBLL
metody object s GetCategories()
.
Obrázek 2: Vytvoření nového objektuDataSource s názvem CategoriesDataSource
(kliknutím zobrazíte obrázek v plné velikosti)
Obrázek 3: Konfigurace objektu ObjectDataSource pro použití CategoriesBLL
třídy (kliknutím zobrazíte obrázek v plné velikosti)
Obrázek 4: Načtení seznamu kategorií pomocí GetCategories()
metody (kliknutím zobrazíte obrázek v plné velikosti)
Po dokončení průvodce Konfigurací zdroje dat visual Studio automaticky přidá BoundField do objektu Categories
GridView pro CategoryID
objekty , CategoryName
, Description
, NumberOfProducts
a BrochurePath
DataColumn
s. Pokračujte a odeberte NumberOfProducts
BoundField, protože GetCategories()
dotaz metody s tyto informace nenačte. Odeberte CategoryID
také BoundField a přejmenujte CategoryName
BrochurePath
vlastnosti BoundFields HeaderText
na Category (Kategorie) a Brožura (v uvedeném pořadí). Po provedení těchto změn by deklarativní značky GridView a ObjectDataSource měly vypadat takto:
<asp:GridView ID="Categories" runat="server"
AutoGenerateColumns="False" DataKeyNames="CategoryID"
DataSourceID="CategoriesDataSource" EnableViewState="False">
<Columns>
<asp:BoundField DataField="CategoryName" HeaderText="Category"
SortExpression="CategoryName" />
<asp:BoundField DataField="Description" HeaderText="Description"
SortExpression="Description" />
<asp:BoundField DataField="BrochurePath" HeaderText="Brochure"
SortExpression="BrochurePath" />
</Columns>
</asp:GridView>
<asp:ObjectDataSource ID="CategoriesDataSource" runat="server"
OldValuesParameterFormatString="original_{0}"
SelectMethod="GetCategories" TypeName="CategoriesBLL">
</asp:ObjectDataSource>
Zobrazte tuto stránku v prohlížeči (viz Obrázek 5). Každá z osmi kategorií je uvedena. Sedm kategorií s BrochurePath
hodnotami má hodnotu zobrazenou BrochurePath
v příslušném BoundField. Mořské plody, které mají NULL
hodnotu pro své BrochurePath
, zobrazí prázdnou buňku.
Obrázek 5: Název, popis a BrochurePath
hodnota každé kategorie je uvedený (kliknutím zobrazíte obrázek v plné velikosti)
Místo zobrazení textu BrochurePath
sloupce chceme vytvořit odkaz na brožuru. Chcete-li to provést, odeberte BrochurePath
BoundField a nahraďte ho HyperLinkField. Nastavte novou vlastnost HyperLinkField na HeaderText
Brožuru, její Text
vlastnost na View Brožura a její DataNavigateUrlFields
vlastnost na BrochurePath
.
Obrázek 6: Přidání hyperlinkfieldu pro BrochurePath
Tím přidáte sloupec odkazů do objektu GridView, jak je znázorněno na obrázku 7. Kliknutím na odkaz Zobrazit brožuru buď zobrazíte soubor PDF přímo v prohlížeči, nebo vyzvete uživatele ke stažení souboru v závislosti na tom, jestli je nainstalovaná čtečka PDF a nastavení prohlížeče.
Obrázek 7: Brožuru kategorie s lze zobrazit kliknutím na odkaz Zobrazit brožuru (kliknutím zobrazíte obrázek v plné velikosti)
Obrázek 8: Zobrazí se pdf brožura kategorie s (kliknutím zobrazíte obrázek v plné velikosti)
Skrytí textu zobrazení brožury pro kategorie bez brožury
Jak ukazuje obrázek 7, BrochurePath
HyperLinkField zobrazuje hodnotu vlastnosti Text
(Zobrazit brožuru) pro všechny záznamy, bez ohledu na to, zda jeNULL
pro BrochurePath
. Samozřejmě, pokud BrochurePath
je NULL
, pak se odkaz zobrazí pouze jako text, stejně jako v případě kategorie Mořské plody (podívejte se zpět na obrázek 7). Místo zobrazení brožury s textem by mohlo být vhodné, aby tyto kategorie bez BrochurePath
hodnoty zobrazovaly alternativní text, například Není k dispozici brožura.
Abychom mohli toto chování poskytnout, musíme použít TemplateField, jehož obsah je generován voláním metody stránky, která vygeneruje příslušný výstup na BrochurePath
základě hodnoty. Tuto techniku formátování jsme poprvé prozkoumali v kurzu Používání polí šablon v ovládacím prvku GridView .
Převeďte HyperLinkField na TemplateField tak, že vyberete BrochurePath
Pole HyperLinkField a potom kliknete na odkaz Převést toto pole na templatefield v dialogovém okně Upravit sloupce.
Obrázek 9: Převod HyperLinkField na TemplateField
Tím se vytvoří TemplateField s objektem ItemTemplate
, který obsahuje webový ovládací prvek HyperLink, jehož NavigateUrl
vlastnost je vázána na BrochurePath
hodnotu. Nahraďte tento kód voláním metody GenerateBrochureLink
, která předává hodnotu BrochurePath
:
<asp:TemplateField HeaderText="Brochure">
<ItemTemplate>
<%# GenerateBrochureLink(Eval("BrochurePath")) %>
</ItemTemplate>
</asp:TemplateField>
Dále vytvořte metodu protected
ve třídě kódu na pozadí stránky ASP.NET s názvem GenerateBrochureLink
, která vrací string
a přijímá object
jako vstupní parametr.
protected string GenerateBrochureLink(object BrochurePath)
{
if (Convert.IsDBNull(BrochurePath))
return "No Brochure Available";
else
return string.Format(@"<a href="{0}">View Brochure</a>",
ResolveUrl(BrochurePath.ToString()));
}
Tato metoda určuje, jestli je předávaná object
hodnota databáze NULL
, a pokud ano, vrátí zprávu oznamující, že v kategorii chybí brožura. Pokud existuje BrochurePath
hodnota, zobrazí se v hypertextovém odkazu. Všimněte si, že pokud BrochurePath
je hodnota k dispozici, předá se do ResolveUrl(url)
metody. Tato metoda přeloží předanou adresu URL a nahradí ~
znak odpovídající virtuální cestou. Pokud je například aplikace rootovaná na adrese /Tutorial55
, ResolveUrl("~/Brochures/Meats.pdf")
vrátí se /Tutorial55/Brochures/Meat.pdf
.
Obrázek 10 znázorňuje stránku po provedení těchto změn. Všimněte si, že v poli Seafood category (Mořské plody) BrochurePath
se teď zobrazuje text No Brožura available (Není k dispozici žádná brožura).
Obrázek 10: Pro kategorie bez brožury se zobrazí text bez brožury (kliknutím zobrazíte obrázek v plné velikosti)
Krok 3: Přidání webové stránky pro zobrazení obrázku kategorie
Když uživatel navštíví stránku ASP.NET, obdrží kód HTML stránky ASP.NET. Přijatý kód HTML je pouze text a neobsahuje žádná binární data. Veškerá další binární data, jako jsou obrázky, zvukové soubory, aplikace Macromedia Flash, vložená Přehrávač médií Windows videa atd., existují na webovém serveru jako samostatné prostředky. Kód HTML obsahuje odkazy na tyto soubory, ale neobsahuje skutečný obsah souborů.
Například v HTML se <img>
element používá k odkazování na obrázek, přičemž src
atribut odkazuje na soubor obrázku takto:
<img src="MyPicture.jpg" ... />
Když prohlížeč obdrží tento kód HTML, odešle webový server další požadavek na načtení binárního obsahu souboru obrázku, který pak zobrazí v prohlížeči. Stejný koncept platí pro všechna binární data. V kroku 2 nebyla brožura odeslána do prohlížeče jako součást kódu HTML stránky. Vykreslený kód HTML místo toho poskytoval hypertextové odkazy, které při kliknutí způsobily, že prohlížeč požádal o dokument PDF přímo.
Abychom uživatelům mohli zobrazit nebo umožnit stahování binárních dat, která se nacházejí v databázi, musíme vytvořit samostatnou webovou stránku, která vrátí data. Pro naši aplikaci je pouze jedno binární datové pole uložené přímo v databázi obrázku kategorie. Proto potřebujeme stránku, která při volání vrátí data obrázku pro určitou kategorii.
Přidejte novou stránku ASP.NET do BinaryData
složky s názvem DisplayCategoryPicture.aspx
. Přitom ponechte políčko Vybrat stránku předlohy nezaškrtnuté. Tato stránka očekává CategoryID
hodnotu v řetězci dotazu a vrátí binární data sloupce dané kategorie Picture
. Vzhledem k tomu, že tato stránka vrací binární data a nic jiného, nepotřebuje v oddílu HTML žádné značky. Proto klikněte na kartu Zdroj v levém dolním rohu a odeberte všechny značky stránky s s výjimkou direktivy <%@ Page %>
. To znamená, DisplayCategoryPicture.aspx
že deklarativní kód by se měl skládat z jednoho řádku:
<%@ Page Language="C#" AutoEventWireup="true"
CodeFile="DisplayCategoryPicture.aspx.cs"
Inherits="BinaryData_DisplayCategoryPicture" %>
Pokud se v direktivě MasterPageFile
<%@ Page %>
zobrazí atribut , odeberte ho.
Do třídy kódu na pozadí stránky přidejte do obslužné rutiny Page_Load
události následující kód:
protected void Page_Load(object sender, EventArgs e)
{
int categoryID = Convert.ToInt32(Request.QueryString["CategoryID"]);
// Get information about the specified category
CategoriesBLL categoryAPI = new CategoriesBLL();
Northwind.CategoriesDataTable categories =
categoryAPI.GetCategoryWithBinaryDataByCategoryID(categoryID);
Northwind.CategoriesRow category = categories[0];
// Output HTTP headers providing information about the binary data
Response.ContentType = "image/bmp";
// Output the binary data
// But first we need to strip out the OLE header
const int OleHeaderLength = 78;
int strippedImageLength = category.Picture.Length - OleHeaderLength;
byte[] strippedImageData = new byte[strippedImageLength];
Array.Copy(category.Picture, OleHeaderLength,
strippedImageData, 0, strippedImageLength);
Response.BinaryWrite(strippedImageData);
}
Tento kód začíná načtením CategoryID
hodnoty řetězce dotazu do proměnné s názvem categoryID
. Dále se data obrázku načtou prostřednictvím volání CategoriesBLL
metody třídy s GetCategoryWithBinaryDataByCategoryID(categoryID)
. Tato data jsou vrácena klientovi pomocí Response.BinaryWrite(data)
metody , ale před zavoláním Picture
je nutné odebrat záhlaví OLE hodnoty sloupce. Toho se dosáhne vytvořením byte
pole s názvem strippedImageData
, které bude obsahovat přesně o 78 znaků méně, než co je ve sloupci Picture
. MetodaArray.Copy
se používá ke zkopírování dat od category.Picture
pozice 78 do strippedImageData
.
Vlastnost Response.ContentType
určuje typ MIME vráceného obsahu, aby prohlížeč věděl, jak ho vykreslit. Categories
Vzhledem k tomu, že Picture
sloupec tabulky je rastrový obrázek, použije se zde typ MIME rastrového obrázku (image/bmp). Pokud vynecháte typ MIME, většina prohlížečů bude i nadále zobrazovat obrázek správně, protože mohou typ odvodit na základě obsahu binárních dat souboru obrázku. Je však vhodné zahrnout typ MIME, pokud je to možné. Úplný seznam typů médií MIME najdete na webu autority pro přiřazená čísla v internetu.
Po vytvoření této stránky si můžete zobrazit konkrétní obrázek kategorie na adrese DisplayCategoryPicture.aspx?CategoryID=categoryID
. Obrázek 11 znázorňuje obrázek kategorie Nápoje, který si můžete prohlédnout na stránce DisplayCategoryPicture.aspx?CategoryID=1
.
Obrázek 11: Zobrazí se obrázek kategorie Nápoje (kliknutím zobrazíte obrázek v plné velikosti)
Pokud při návštěvě DisplayCategoryPicture.aspx?CategoryID=categoryID
nástroje dojde k výjimce s textem Nelze přetypovat objekt typu System.DBNull na typ System.Byte[], můžou to způsobovat dvě věci. Za prvé, Categories
sloupec s Picture
tabulky povoluje NULL
hodnoty. Stránka DisplayCategoryPicture.aspx
ale předpokládá, že existuje hodnota, která neníNULL
. Vlastnost Picture
objektu CategoriesDataTable
nemůže být přímo přístupná, pokud má NULL
hodnotu. Pokud chcete povolit NULL
hodnoty pro Picture
sloupec, měli byste zahrnout následující podmínku:
if (category.IsPictureNull())
{
// Display some "No Image Available" picture
Response.Redirect("~/Images/NoPictureAvailable.gif");
}
else
{
// Send back the binary contents of the Picture column
// ... Set ContentType property and write out ...
// ... data via Response.BinaryWrite ...
}
Výše uvedený kód předpokládá, že ve Images
složce, kterou chcete zobrazit pro tyto kategorie bez obrázku, existuje soubor obrázku s názvem NoPictureAvailable.gif
.
K této výjimce může dojít také v případě, že CategoriesTableAdapter
se příkaz s metody SELECT
s GetCategoryWithBinaryDataByCategoryID
vrátil zpět na seznam sloupců hlavního dotazu, k čemuž může dojít, pokud používáte ad hoc příkazy SQL a znovu spustíte průvodce pro hlavní dotaz TableAdapter. Zkontrolujte, jestli GetCategoryWithBinaryDataByCategoryID
příkaz metody SELECT
s stále obsahuje Picture
sloupec .
Poznámka
Při DisplayCategoryPicture.aspx
každé návštěvě dojde k přístupu k databázi a vrátí se data obrázku zadané kategorie. Pokud se ale obrázek kategorie od posledního zobrazení uživatele nezměnil, je to zbytečné úsilí. Protokol HTTP naštěstí umožňuje podmíněné operace GET. Při podmíněném příkazu GET klient, který provádí požadavek HTTP, odesílá spolu s hlavičkouIf-Modified-Since
PROTOKOLU HTTP, která poskytuje datum a čas, kdy klient naposledy načetl tento prostředek z webového serveru. Pokud se obsah od tohoto zadaného data nezměnil, webový server může odpovědět stavovým kódem 304(304) a neodeslat zpět obsah požadovaného prostředku. Stručně řečeno, tato technika zbavuje webový server nutnosti odesílat zpět obsah pro prostředek, pokud nebyl změněn od posledního přístupu klienta.
K implementaci tohoto chování ale musíte do tabulky přidat PictureLastModified
sloupec, který zaznamená, kdy Picture
byl sloupec naposledy aktualizován, a také kód pro kontrolu hlavičkyIf-Modified-Since
.Categories
Další informace o If-Modified-Since
hlavičce a podmíněném pracovním postupu GET najdete v tématech PODMÍNĚNÝ PŘÍKAZ HTTP pro hackery RSS a Podrobnější pohled na provádění požadavků HTTP na stránce ASP.NET.
Krok 4: Zobrazení obrázků kategorií v GridView
Teď, když máme webovou stránku pro zobrazení konkrétního obrázku kategorie, můžeme ho zobrazit pomocí ovládacího prvku Obrázek webu nebo elementu HTML <img>
odkazujícího na DisplayCategoryPicture.aspx?CategoryID=categoryID
. Obrázky, jejichž adresa URL je určena databázová data lze zobrazit v GridView nebo DetailsView pomocí ImageField. ImageField obsahuje DataImageUrlField
vlastnosti a DataImageUrlFormatString
, které fungují stejně jako HyperLinkField DataNavigateUrlFields
a DataNavigateUrlFormatString
vlastnosti.
Pojďme rozšířit Categories
GridView v o DisplayOrDownloadData.aspx
přidání ImageField, aby se zobrazily obrázky jednotlivých kategorií. Jednoduše přidejte Pole ImageField a nastavte jeho DataImageUrlField
vlastnosti a DataImageUrlFormatString
na CategoryID
a DisplayCategoryPicture.aspx?CategoryID={0}
. Tím se vytvoří sloupec GridView, který vykreslí <img>
prvek, jehož src
atribut odkazuje na DisplayCategoryPicture.aspx?CategoryID={0}
, kde {0} je nahrazen hodnotou GridView řádku s CategoryID
.
Obrázek 12: Přidání ImageField do GridView
Po přidání ImageField by deklarativní syntaxe objektu GridView měla vypadat takto:
<asp:GridView ID="Categories" runat="server" AutoGenerateColumns="False"
DataKeyNames="CategoryID" DataSourceID="CategoriesDataSource"
EnableViewState="False">
<Columns>
<asp:BoundField DataField="CategoryName" HeaderText="Category"
SortExpression="CategoryName" />
<asp:BoundField DataField="Description" HeaderText="Description"
SortExpression="Description" />
<asp:TemplateField HeaderText="Brochure">
<ItemTemplate>
<%# GenerateBrochureLink(Eval("BrochurePath")) %>
</ItemTemplate>
</asp:TemplateField>
<asp:ImageField DataImageUrlField="CategoryID"
DataImageUrlFormatString="DisplayCategoryPicture.aspx?CategoryID={0}">
</asp:ImageField>
</Columns>
</asp:GridView>
Chvíli se na tuto stránku podívejte v prohlížeči. Všimněte si, že každý záznam teď obsahuje obrázek kategorie.
Obrázek 13: Obrázek kategorie se zobrazí pro každý řádek (kliknutím zobrazíte obrázek v plné velikosti)
Souhrn
V tomto kurzu jsme se zabývali tím, jak prezentovat binární data. Způsob prezentace dat závisí na typu dat. Pro soubory brožur PDF jsme uživateli nabídli odkaz Zobrazit brožuru, který po kliknutí přenesl uživatele přímo do souboru PDF. Pro obrázek kategorie jsme nejprve vytvořili stránku pro načtení a vrácení binárních dat z databáze a pak jsme ji použili k zobrazení obrázků jednotlivých kategorií v objektu GridView.
Teď, když jsme se podívali na to, jak zobrazit binární data, jsme připraveni prozkoumat, jak provádět vkládání, aktualizace a odstraňování v databázi s binárními daty. V dalším kurzu se podíváme na to, jak přidružit nahraný soubor k odpovídajícímu záznamu databáze. V dalším kurzu se dozvíte, jak aktualizovat existující binární data a jak odstranit binární data při odebrání přidruženého záznamu.
Všechno nejlepší na programování!
O autorovi
Scott Mitchell, autor sedmi knih o ASP/ASP.NET a zakladatel 4GuysFromRolla.com, pracuje s webovými technologiemi Microsoftu od roku 1998. Scott pracuje jako nezávislý konzultant, školitel a spisovatel. Jeho nejnovější kniha je Sams Teach Yourself ASP.NET 2.0 in 24 Hours. Můžete ho zastihnout na mitchell@4GuysFromRolla.comadrese . nebo prostřednictvím jeho blogu, který najdete na adrese http://ScottOnWriting.NET.
Zvláštní poděkování
Tato série kurzů byla zkontrolována mnoha užitečnými recenzenty. Hlavními recenzenty pro tento kurz byli Teresa Murphy a Dave Gardner. Chtěli byste si projít své nadcházející články na webu MSDN? Pokud ano, dejte mi řádek na mitchell@4GuysFromRolla.com.
Váš názor
https://aka.ms/ContentUserFeedback.
Připravujeme: V průběhu roku 2024 budeme postupně vyřazovat problémy z GitHub coby mechanismus zpětné vazby pro obsah a nahrazovat ho novým systémem zpětné vazby. Další informace naleznete v tématu:Odeslat a zobrazit názory pro