Zobrazení binárních dat ve webových ovládacích prvcích dat (VB)
Scott Mitchell
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 Ke stažení 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 přidružit nahraná binární data 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žená přímo v databázi, pak se nahraná binární data nemusí ukládat 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, pojďme se nejprve podívat, jak koncovému uživateli poskytnout binární data. Prezentace textových dat je dostatečně jednoduchá, ale jak by se měla binární data prezentovat? Záleží samozřejmě na typu binárních dat. U obrázků pravděpodobně chceme zobrazit obrázek; v případě souborů PDF, dokumentů Aplikace 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í datových webových ovládacích prvků, 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 Categories
tabulce již obsahuje binární data pro různé obrázky kategorií. Picture
Konkrétně sloupec pro každý záznam obsahuje binární obsah odstupňovaného, nízké kvality, 16barevného rastrového obrázku. Každý obrázek kategorie je 172 pixelů široký a 120 pixelů vysoký a spotřebuje přibližně 11 kB. Binární obsah ve Picture
sloupci navíc obsahuje hlavičku OLE o 78 bajtů, která musí být před zobrazením obrázku oříznuta. Tyto informace v 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 OBJEKT OLE, který se přichytá na této hlavičce. Prozatím uvidíme, jak z těchto obrázků s nízkou kvalitou odstranit záhlaví, aby se obrázek zobrazil. V dalším kurzu vytvoříme rozhraní pro aktualizaci sloupce kategorií Picture
a nahradíme tyto rastrové obrázky, které používají hlavičky OLE ekvivalentními obrázky JPG bez zbytečných hlaviček 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 Categories
tabulce. V dalším kurzu se dozvíme, jak toho dosáhnout, ale prozatím potřebujeme zadat hodnoty pro tento sloupec ručně.
V tomto kurzu ke stažení najdete sedm souborů brožur PDF ve ~/Brochures
složce, jeden pro každou z kategorií kromě mořské plody. Záměrně jsem vynechal přidání brožury seafood, která ilustruje, jak zvládnout scénáře, kdy ne všechny záznamy mají přidružená binární data. Pokud chcete tabulku aktualizovat Categories
těmito hodnotami, klikněte pravým tlačítkem myši na uzel z Průzkumníka Categories
serveru a zvolte Zobrazit data tabulky. Potom zadejte virtuální cesty k souborům brožury pro každou kategorii, která má brožuru, jak ukazuje obrázek 1. Vzhledem k tomu, že neexistuje žádná brožura pro kategorii Mořské plody, ponechte její BrochurePath
sloupec hodnotu jako NULL
.
Obrázek 1: Ručně zadejte hodnoty sloupce Categories
tabulky BrochurePath
(kliknutím zobrazíte obrázek s plnou velikostí).
Krok 2: Poskytnutí odkazu ke stažení brožur v GridView
BrochurePath
S hodnotami zadanými pro Categories
tabulku jsme připraveni vytvořit GridView, který obsahuje každou kategorii spolu s odkazem ke stažení brožury kategorie. V kroku 4 rozšíříme toto zobrazení GridView, aby se zobrazil také obrázek kategorie.
Začněte přetažením objektu GridView ze sady nástrojů do Návrháře DisplayOrDownloadData.aspx
stránky ve BinaryData
složce. Nastavte GridView na ID
Categories
a prostřednictvím inteligentní značky GridView s, zvolte, aby se svážel s novým zdrojem dat. Konkrétně vytvořte vazbu na ObjectDataSource s názvem CategoriesDataSource
, který načítá data pomocí metody objektu CategoriesBLL
GetCategories()
.
Obrázek 2: Vytvoření nového objektu ObjectDataSource s názvem CategoriesDataSource
(kliknutím zobrazíte obrázek s plnou velikostí)
Obrázek 3: Konfigurace ObjectDataSource pro použití CategoriesBLL
třídy (kliknutím zobrazíte obrázek s plnou velikostí)
Obrázek 4: Načtení seznamu kategorií pomocí GetCategories()
metody (kliknutím zobrazíte obrázek s plnou velikostí)
Po dokončení průvodce konfigurací zdroje dat sada Visual Studio automaticky přidá BoundField do Categories
GridView pro objekt CategoryID
, CategoryName
, Description
NumberOfProducts
a s BrochurePath
DataColumn
. Pokračujte a odeberte NumberOfProducts
BoundField, protože GetCategories()
dotaz metody nenačte tyto informace. Odeberte CategoryID
také BoundField a přejmenujte CategoryName
BrochurePath
vlastnosti BoundFields HeaderText
na Category a Brochure( v uvedeném pořadí). Po provedení těchto změn by deklarativní kód 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>
Umožňuje zobrazit tuto stránku v prohlížeči (viz obrázek 5). Každá z osmi kategorií je uvedena. Sedm kategorií s BrochurePath
hodnotami mají BrochurePath
hodnotu zobrazenou v příslušném BoundField. Plody moře, které mají NULL
hodnotu pro své BrochurePath
, zobrazí prázdnou buňku.
Obrázek 5: Zobrazí se název, popis a BrochurePath
hodnota každé kategorie (kliknutím zobrazíte obrázek s plnou velikostí).
Místo zobrazení textu BrochurePath
sloupce chceme vytvořit odkaz na brožuru. Chcete-li toho dosáhnout, odeberte BrochurePath
BoundField a nahraďte ho HyperLinkField. Nastavte novou vlastnost HyperLinkField HeaderText
na Brožuru, jeho Text
vlastnost Zobrazit brožuru a jeho DataNavigateUrlFields
vlastnost na BrochurePath
.
Obrázek 6: Přidání HyperLinkFieldu pro BrochurePath
Tím přidáte sloupec odkazů na GridView, jak ukazuje obrázek 7. Kliknutím na odkaz Zobrazit brožuru se soubor PDF zobrazí přímo v prohlížeči nebo vyzve 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 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 (kliknutím zobrazíte obrázek v plné velikosti).
Skrytí textu brožury zobrazení pro kategorie bez brožury
Jak ukazuje obrázek 7, BrochurePath
HyperLinkField zobrazí jeho Text
hodnotu vlastnosti (Zobrazit brožuru) pro všechny záznamy bez ohledu na to, zda existuje jináNULL
hodnota než hodnota BrochurePath
. Pokud anoNULL
, BrochurePath
odkaz se samozřejmě zobrazí pouze jako text, stejně jako v případě kategorie Mořské plody (odkaz zpět na obrázek 7). Místo zobrazení brožury pro zobrazení textu může být vhodné mít tyto kategorie bez BrochurePath
hodnoty zobrazit alternativní text, například Žádná brožura k dispozici.
Abychom mohli toto chování poskytnout, musíme použít TemplateField, jehož obsah je generován voláním metody stránky, která generuje odpovídající výstup na BrochurePath
základě hodnoty. Tuto techniku formátování jsme poprvé prozkoumali zpět v kurzu Použití TemplateFields v ovládacím prvku GridView .
Převeďte HyperLinkField na TemplateField tak BrochurePath
, že vyberete HyperLinkField a potom kliknete na převést toto pole na odkaz TemplateField v dialogovém okně Upravit sloupce.
Obrázek 9: Převod HyperLinkFieldu na TemplateField
Tím vytvoříte TemplateField s ovládacím ItemTemplate
prvku HyperLink Web, jehož NavigateUrl
vlastnost je vázána BrochurePath
na hodnotu. Nahraďte tento kód voláním metody GenerateBrochureLink
a předejte hodnotu BrochurePath
:
<asp:TemplateField HeaderText="Brochure">
<ItemTemplate>
<%# GenerateBrochureLink(Eval("BrochurePath")) %>
</ItemTemplate>
</asp:TemplateField>
Dále vytvořte metodu Protected
na ASP.NET stránce s kódem třídy s názvem GenerateBrochureLink
, která vrací String
a přijímá Object
jako vstupní parametr.
Protected Function GenerateBrochureLink(BrochurePath As Object) As String
If Convert.IsDBNull(BrochurePath) Then
Return "No Brochure Available"
Else
Return String.Format("<a href="{0}">View Brochure</a>", _
ResolveUrl(BrochurePath.ToString()))
End If
End Function
Tato metoda určuje, zda předaná Object
hodnota je databáze NULL
, a pokud ano, vrátí zprávu, že kategorie nemá brožuru. V opačném případě se v případě BrochurePath
hodnoty zobrazí v hypertextovém odkazu. Všimněte si, že pokud je hodnota BrochurePath
přítomna, předá do ResolveUrl(url)
metody. Tato metoda přeloží předanou adresu URL a nahradí ~
znak příslušnou virtuální cestou. Pokud je například aplikace kořenem /Tutorial55
ResolveUrl("~/Brochures/Meats.pdf")
, vrátí /Tutorial55/Brochures/Meat.pdf
.
Obrázek 10 ukazuje stránku po použití těchto změn. Všimněte si, že pole kategorie BrochurePath
mořské plody nyní zobrazuje text Bez brožury k dispozici .
Obrázek 10: Pro tyto kategorie bez brožury se nezobrazuje 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í ASP.NET stránku, obdrží kód HTML ASP.NET stránky. Přijatý kód HTML je pouze text a neobsahuje žádná binární data. Jakákoli další binární data, jako jsou obrázky, zvukové soubory, aplikace Macromedia Flash, vložená Přehrávač médií Windows videa atd., existují jako samostatné prostředky na webovém serveru. 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 s src
atributem odkazujícím na soubor obrázku, například takto:
<img src="MyPicture.jpg" ... />
Když prohlížeč obdrží tento kód HTML, odešle webovému serveru další požadavek na načtení binárního obsahu souboru obrázku, který se pak zobrazí v prohlížeči. Stejný koncept platí pro všechna binární data. V kroku 2 se brožura neodeslala do prohlížeče jako součást kódu HTML stránky. Vykreslené html poskytnuté hypertextové odkazy, které při kliknutí způsobily, že prohlížeč požádal přímo o dokument PDF.
Abychom uživatelům mohli zobrazit nebo povolit stahování binárních dat, která se nacházejí v databázi, musíme vytvořit samostatnou webovou stránku, která vrací data. Pro naši aplikaci existuje pouze jedno binární datové pole uložené přímo v databázi s obrázkem kategorie. Proto potřebujeme stránku, která při zavolá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
. Když to uděláte, nechte 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 žádné značky v oddílu HTML. Proto klikněte na kartu Zdroj v levém dolním rohu a odeberte všechny značky stránky s výjimkou direktivy <%@ Page %>
. DisplayCategoryPicture.aspx
Deklarativní kód by se tedy měl skládat z jednoho řádku:
<%@ Page Language="VB" AutoEventWireup="true"
CodeFile="DisplayCategoryPicture.aspx.vb"
Inherits="BinaryData_DisplayCategoryPicture" %>
Pokud se v direktivě <%@ Page %>
zobrazí MasterPageFile
atribut, odeberte ho.
Do třídy kódu stránky přidejte do Page_Load
obslužné rutiny události následující kód:
Protected Sub Page_Load(sender As Object, e As EventArgs) Handles Me.Load
Dim categoryID As Integer = _
Convert.ToInt32(Request.QueryString("CategoryID"))
' Get information about the specified category
Dim categoryAPI As New CategoriesBLL()
Dim categories As Northwind.CategoriesDataTable = _
categoryAPI.GetCategoryWithBinaryDataByCategoryID(categoryID)
Dim category As Northwind.CategoriesRow = 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 OleHeaderLength As Integer = 78
Dim strippedImageLength As Integer = _
category.Picture.Length - OleHeaderLength
Dim strippedImageData(strippedImageLength) As Byte
Array.Copy(category.Picture, OleHeaderLength, _
strippedImageData, 0, strippedImageLength)
Response.BinaryWrite(strippedImageData)
End Sub
Tento kód začíná čtením v hodnotě CategoryID
řetězce dotazu do proměnné s názvem categoryID
. Dále se data obrázku načtou voláním CategoriesBLL
metody třídy.GetCategoryWithBinaryDataByCategoryID(categoryID)
Tato data se klientovi vrátí pomocí Response.BinaryWrite(data)
metody, ale před tím, než je volána, Picture
musí být odebrána hlavička OLE hodnoty sloupce. Toho dosáhnete vytvořením pole s Byte
názvem strippedImageData
, které bude obsahovat přesně 78 znaků menší než to, co je ve sloupci Picture
. Metoda Array.Copy
se používá ke kopí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. Vzhledem k tomu, že Categories
sloupec tabulky Picture
je rastrový obrázek, použije se zde typ MIME rastrového obrázku (obrázek/bmp). Pokud typ MIME vynecháte, většina prohlížečů bude i nadále zobrazovat obrázek správně, protože může odvodit typ 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 internetová přiřazená čísla.
Po vytvoření této stránky si můžete prohlédnout obrázek konkrétní kategorie na DisplayCategoryPicture.aspx?CategoryID=categoryID
webu . Obrázek 11 znázorňuje obrázek kategorie Nápoje, který lze zobrazit z DisplayCategoryPicture.aspx?CategoryID=1
.
Obrázek 11: Obrázek kategorie nápojů se zobrazí (kliknutím zobrazíte obrázek v plné velikosti).
Pokud při návštěvě DisplayCategoryPicture.aspx?CategoryID=categoryID
získáte výjimku, která přečte, že nelze přetypovat objekt typu System.DBNull na typ System.Byte[], existují dvě věci, které mohou být příčinou. Categories
Nejprve sloupec tabulky Picture
povoluje NULL
hodnoty. Stránka DisplayCategoryPicture.aspx
však předpokládá, že existuje jináNULL
hodnota. Vlastnost Picture
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() Then
' 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 ...
End If
Výše uvedený kód předpokládá, že ve Images
složce, kterou chcete zobrazit pro tyto kategorie bez obrázku, existuje nějaký soubor NoPictureAvailable.gif
obrázku.
K této výjimce může dojít také v případě, že CategoriesTableAdapter
se příkaz metody s GetCategoryWithBinaryDataByCategoryID
SELECT
vrátil zpět do seznamu sloupců hlavního dotazu, ke kterému může dojít, pokud používáte příkazy SQL ad hoc a znovu spustíte průvodce pro hlavní dotaz TableAdapter. Zkontrolujte, jestli GetCategoryWithBinaryDataByCategoryID
příkaz metody SELECT
stále obsahuje Picture
sloupec.
Poznámka:
Při každém navštívení DisplayCategoryPicture.aspx
se databáze dostane k databázi a vrátí se zadaná data obrázků kategorií. Pokud se obrázek kategorie od posledního zobrazení uživatele nezměnil, je to ale plýtvání úsilím. Http naštěstí umožňuje podmíněné gety. Pomocí podmíněného get klient odešle požadavek HTTP spolu s hlavičkou If-Modified-Since
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 Not Modified (304) a odeslat zpět požadovaný obsah prostředků. Stručně řečeno, tato technika zbavuje webového serveru nutnosti odesílat zpět obsah pro prostředek, pokud nebyl změněn od posledního přístupu klienta.
Pokud chcete toto chování implementovat, musíte do tabulky přidat PictureLastModified
sloupec, který bude zaznamenávat, kdy Picture
byl sloupec naposledy aktualizován, a také kód pro kontrolu If-Modified-Since
Categories
záhlaví. Další informace o If-Modified-Since
hlavičce a podmíněném pracovním postupu GET naleznete v tématu HTTP Conditional GET for RSS Hackers and A Deeper Look at Performing HTTP Requests in an ASP.NET Page.
Krok 4: Zobrazení obrázků kategorií v objektu GridView
Když teď máme webovou stránku k zobrazení obrázku konkrétní kategorie, můžeme ji zobrazit pomocí ovládacího prvku Obrázek web nebo element HTML <img>
odkazující na DisplayCategoryPicture.aspx?CategoryID=categoryID
. Obrázky, jejichž adresa URL je určena databázovými daty, lze zobrazit v Objektu GridView nebo DetailsView pomocí ImageField. ImageField obsahuje DataImageUrlField
a DataImageUrlFormatString
vlastnosti, které fungují jako HyperLinkField s DataNavigateUrlFields
a DataNavigateUrlFormatString
vlastnosti.
Pojďme gridView DisplayOrDownloadData.aspx
rozšířit Categories
přidáním ImageField k zobrazení každého obrázku kategorie. Jednoduše přidejte ImageField a nastavte jeho DataImageUrlField
a DataImageUrlFormatString
vlastnosti na CategoryID
a DisplayCategoryPicture.aspx?CategoryID={0}
v uvedeném pořadí. Tím se vytvoří sloupec GridView, který vykreslí <img>
prvek, jehož src
atributy odkazy DisplayCategoryPicture.aspx?CategoryID={0}
, kde {0} je nahrazena hodnotou řádku CategoryID
GridView.
Obrázek 12: Přidání imageField do objektu GridView
Po přidání ImageField by deklarativní syntaxe 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>
Chvilku si tuto stránku prohlédněte v prohlížeči. Všimněte si, že každý záznam teď obsahuje obrázek pro kategorii.
Obrázek 13: Obrázek kategorie se zobrazí pro každý řádek (kliknutím zobrazíte obrázek v plné velikosti).
Shrnutí
V tomto kurzu jsme prozkoumali, jak prezentovat binární data. Způsob zobrazení dat závisí na typu dat. Pro soubory brožury PDF jsme uživateli nabídli odkaz zobrazit brožuru, který uživatel po kliknutí vzal přímo do souboru PDF. Pro obrázek kategorie jsme nejprve vytvořili stránku, která načte a vrátí binární data z databáze, a pak jsme ji použili k zobrazení každého obrázku kategorie v 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, jak přidružit nahraný soubor k odpovídajícímu záznamu databáze. V tomto 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.
Šťastné programování!
O autorovi
Scott Mitchell, autor sedmi knih ASP/ASP.NET a zakladatel 4GuysFromRolla.com, pracuje s webovými technologiemi Microsoftu od roku 1998. Scott pracuje jako nezávislý konzultant, trenér a spisovatel. Jeho nejnovější kniha je Sams Teach Yourself ASP.NET 2.0 za 24 hodin. Je dostupný na mitchell@4GuysFromRolla.comadrese . nebo prostřednictvím svého blogu, který lze najít na http://ScottOnWriting.NET.
Zvláštní díky
Tato série kurzů byla zkontrolována mnoha užitečnými recenzenty. Vedoucí hodnotící pro tento kurz byli Teresa Murphy a Dave Gardner. Chcete si projít nadcházející články MSDN? Pokud ano, zahoďte mi řádek na mitchell@4GuysFromRolla.com.