Visualizzazione di dati binari nei controlli Web dei dati (VB)
In questa esercitazione vengono esaminate le opzioni per presentare i dati binari in una pagina Web, inclusa la visualizzazione di un file di immagine e il provisioning di un collegamento "Download" per un file PDF.
Introduzione
Nell'esercitazione precedente sono state esaminate le due tecniche per l'associazione di dati binari a un modello di dati sottostante di un'applicazione e il controllo FileUpload per caricare i file da un browser al file system del server Web. È stato ancora illustrato come associare i dati binari caricati al modello di dati. Ovvero, dopo che un file è stato caricato e salvato nel file system, è necessario archiviare un percorso del file nel record di database appropriato. Se i dati vengono archiviati direttamente nel database, i dati binari caricati non devono essere salvati nel file system, ma devono essere inseriti nel database.
Prima di esaminare l'associazione dei dati al modello di dati, è possibile esaminare prima di tutto come fornire i dati binari all'utente finale. La presentazione dei dati di testo è abbastanza semplice, ma come devono essere presentati i dati binari? Dipende naturalmente dal tipo di dati binari. Per le immagini, è probabile che si voglia visualizzare l'immagine; per pdf, documenti di Microsoft Word, file ZIP e altri tipi di dati binari, fornendo un collegamento Download è probabilmente più appropriato.
In questa esercitazione verrà illustrato come presentare i dati binari insieme ai dati di testo associati usando controlli Web dati come GridView e DetailsView. Nell'esercitazione successiva verrà rivolta l'attenzione all'associazione di un file caricato al database.
Passaggio 1: SpecificareBrochurePath
valori
La Picture
colonna nella Categories
tabella contiene già dati binari per le varie immagini di categoria. In particolare, la Picture
colonna per ogni record contiene il contenuto binario di un'immagine bitmap a 16 colori e granulare. Ogni immagine di categoria è 172 pixel di larghezza e 120 pixel di altezza e consuma circa 11 KB. Inoltre, il contenuto binario nella Picture
colonna include un'intestazione OLE a 78 byte che deve essere rimossa prima di visualizzare l'immagine. Queste informazioni sull'intestazione sono presenti perché il database Northwind ha le sue radici in Microsoft Access. In Access i dati binari vengono archiviati usando il tipo di dati OLE Object, che consente di usare questa intestazione. Per il momento, vedremo come rimuovere le intestazioni da queste immagini di bassa qualità per visualizzare l'immagine. In un'esercitazione futura verrà creata un'interfaccia per aggiornare una colonna della Picture
categoria e sostituire queste immagini bitmap che usano intestazioni OLE con immagini JPG equivalenti senza le intestazioni OLE non necessarie.
Nell'esercitazione precedente è stato illustrato come usare il controllo FileUpload. È quindi possibile procedere e aggiungere file brochure al file system del server Web. In questo modo, tuttavia, non aggiorna la BrochurePath
colonna nella Categories
tabella. Nell'esercitazione successiva verrà illustrato come eseguire questa operazione, ma per il momento è necessario fornire manualmente i valori per questa colonna.
In questa esercitazione si scaricano sette file di brochure PDF nella ~/Brochures
cartella, uno per ognuna delle categorie tranne Pesce. Ho omesso intenzionalmente di aggiungere una brochure pesce per illustrare come gestire scenari in cui non tutti i record hanno associato dati binari. Per aggiornare la Categories
tabella con questi valori, fare clic con il pulsante destro del mouse sul Categories
nodo da Esplora server e scegliere Mostra dati tabella. Immettere quindi i percorsi virtuali per i file della brochure per ogni categoria con una brochure, come illustrato nella figura 1. Poiché non esiste una brochure per la categoria Pesce, lasciare il BrochurePath
valore della colonna come NULL
.
Figura 1: Immettere manualmente i valori per la Categories
colonna della BrochurePath
tabella (fare clic per visualizzare l'immagine a dimensione intera)
Passaggio 2: Fornire un collegamento di download per le brochure in un controllo GridView
Con i BrochurePath
valori forniti per la Categories
tabella, è possibile creare un controllo GridView che elenca ogni categoria insieme a un collegamento per scaricare la brochure della categoria. Nel passaggio 4 verrà esteso questo controllo GridView per visualizzare anche l'immagine della categoria.
Per iniziare, trascinare gridView dalla casella degli strumenti nella finestra di progettazione della DisplayOrDownloadData.aspx
pagina nella BinaryData
cartella . Impostare GridView s ID
su Categories
e tramite lo smart tag gridView, scegliere di associarlo a una nuova origine dati. In particolare, associarlo a un ObjectDataSource denominato CategoriesDataSource
che recupera i dati usando il metodo dell'oggetto CategoriesBLL
GetCategories()
.
Figura 2: Creare un nuovo oggettoDataSource denominato CategoriesDataSource
(fare clic per visualizzare l'immagine a dimensione intera)
Figura 3: Configurare ObjectDataSource per l'uso della classe (fare clic per visualizzare l'immagine CategoriesBLL
a dimensione intera)
Figura 4: Recuperare l'elenco delle categorie utilizzando il GetCategories()
metodo (fare clic per visualizzare l'immagine a dimensione intera)
Dopo aver completato la procedura guidata Configura origine dati, Visual Studio aggiungerà automaticamente un oggetto BoundField a Categories
GridView per CategoryID
, CategoryName
Description
, NumberOfProducts
, e BrochurePath
DataColumn
s. Procedere e rimuovere BoundField NumberOfProducts
perché la GetCategories()
query del metodo non recupera queste informazioni. Rimuovere anche le CategoryID
proprietà BoundField e rinominare rispettivamente le CategoryName
proprietà BoundFields BrochurePath
HeaderText
e Category e Brochure. Dopo aver apportato queste modifiche, il markup dichiarativo di GridView e ObjectDataSource dovrebbe essere simile al seguente:
<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>
Visualizzare questa pagina tramite un browser (vedere la figura 5). Ognuna delle otto categorie è elencata. Le sette categorie con BrochurePath
valori hanno il BrochurePath
valore visualizzato nel rispettivo BoundField. Pesce, che ha un NULL
valore per il relativo BrochurePath
, visualizza una cella vuota.
Figura 5: Ogni nome, descrizione e BrochurePath
valore di ogni categoria è elencato (fare clic per visualizzare l'immagine a dimensione intera)
Invece di visualizzare il testo della BrochurePath
colonna, si vuole creare un collegamento alla brochure. A tale scopo, rimuovere BoundField BrochurePath
e sostituirlo con un Oggetto HyperLinkField. Impostare la nuova proprietà HyperLinkField su HeaderText
Brochure, la relativa Text
proprietà su View Brochure e la relativa DataNavigateUrlFields
proprietà su BrochurePath
.
Figura 6: Aggiungere un oggetto HyperLinkField per BrochurePath
Verrà aggiunta una colonna di collegamenti a GridView, come illustrato nella figura 7. Facendo clic su un collegamento Visualizza brochure verrà visualizzato il PDF direttamente nel browser o viene richiesto all'utente di scaricare il file, a seconda che sia installato un lettore PDF e le impostazioni del browser.
Figura 7: La brochure di una categoria può essere visualizzata facendo clic sul collegamento Visualizza brochure (fare clic per visualizzare l'immagine a dimensione intera)
Figura 8: Viene visualizzato il pdf della brochure della categoria (fare clic per visualizzare l'immagine a dimensione intera)
Nascondere il testo della brochure di visualizzazione per le categorie senza una brochure
Come illustrato nella figura 7, HyperLinkField visualizza il Text
valore della BrochurePath
proprietà ( View Brochure ) per tutti i record, indipendentemente dal fatto che sia presente un valore diversoNULL
da .BrochurePath
Naturalmente, se BrochurePath
è NULL
, il collegamento viene visualizzato solo come testo, come nel caso della categoria Pesce (fare riferimento alla figura 7). Invece di visualizzare il testo View Brochure, potrebbe essere bello avere tali categorie senza un valore visualizzare un BrochurePath
testo alternativo, ad esempio No Brochure Available.
Per fornire questo comportamento, è necessario usare un Oggetto TemplateField il cui contenuto viene generato tramite una chiamata a un metodo di pagina che genera l'output appropriato in base al BrochurePath
valore. Questa tecnica di formattazione è stata esaminata in primo luogo nell'esercitazione Uso di TemplateFields nell'esercitazione sul controllo GridView.
Trasformare HyperLinkField in un campo modello selezionando BrochurePath
HyperLinkField e quindi facendo clic sul collegamento Converti questo campo in un campo Modello nella finestra di dialogo Modifica colonne.
Figura 9: Convertire HyperLinkField in un campo template
Verrà creato un oggetto TemplateField con un ItemTemplate
oggetto contenente un controllo Web HyperLink la cui NavigateUrl
proprietà è associata al BrochurePath
valore. Sostituire questo markup con una chiamata al metodo GenerateBrochureLink
, passando il valore di BrochurePath
:
<asp:TemplateField HeaderText="Brochure">
<ItemTemplate>
<%# GenerateBrochureLink(Eval("BrochurePath")) %>
</ItemTemplate>
</asp:TemplateField>
Creare quindi un Protected
metodo nella classe code-behind della pagina ASP.NET denominata GenerateBrochureLink
che restituisce e accetta un String
oggetto Object
come parametro di input.
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
Questo metodo determina se il valore passato Object
è un database NULL
e, in tal caso, restituisce un messaggio che indica che la categoria non dispone di una brochure. In caso contrario, se è presente un BrochurePath
valore, viene visualizzato in un collegamento ipertestuale. Si noti che se il BrochurePath
valore è presente, viene passato al ResolveUrl(url)
metodo . Questo metodo risolve l'URL passato, sostituendo il ~
carattere con il percorso virtuale appropriato. Ad esempio, se l'applicazione è rooted in /Tutorial55
, ResolveUrl("~/Brochures/Meats.pdf")
restituirà /Tutorial55/Brochures/Meat.pdf
.
La figura 10 mostra la pagina dopo l'applicazione di queste modifiche. Si noti che il campo Categoria BrochurePath
Pesce ora visualizza il testo No Brochure Available .
Figura 10: Il testo nessun opuscolo disponibile viene visualizzato per tali categorie senza brochure (fare clic per visualizzare l'immagine a dimensione intera)
Passaggio 3: Aggiunta di una pagina Web per visualizzare un'immagine della categoria
Quando un utente visita una pagina ASP.NET, riceve il codice HTML della pagina ASP.NET. Il codice HTML ricevuto è solo testo e non contiene dati binari. Eventuali dati binari aggiuntivi, ad esempio immagini, file audio, applicazioni Macromedia Flash, video incorporati Lettore multimediale Windows e così via, esistono come risorse separate nel server Web. Il codice HTML contiene riferimenti a questi file, ma non include il contenuto effettivo dei file.
Ad esempio, in HTML l'elemento <img>
viene usato per fare riferimento a un'immagine, con l'attributo src
che punta al file di immagine come indicato di seguito:
<img src="MyPicture.jpg" ... />
Quando un browser riceve questo codice HTML, effettua un'altra richiesta al server Web per recuperare il contenuto binario del file di immagine, che viene quindi visualizzato nel browser. Lo stesso concetto si applica a qualsiasi dato binario. Nel passaggio 2, la brochure non è stata inviata al browser come parte del markup HTML della pagina. Invece, il codice HTML sottoposto a rendering ha fornito collegamenti ipertestuali che, quando si fa clic, ha causato la richiesta diretta del documento PDF da parte del browser.
Per visualizzare o consentire agli utenti di scaricare dati binari che risiedono all'interno del database, è necessario creare una pagina Web separata che restituisca i dati. Per l'applicazione è presente un solo campo dati binario archiviato direttamente nel database l'immagine della categoria. Pertanto, è necessaria una pagina che, quando viene chiamata, restituisce i dati dell'immagine per una determinata categoria.
Aggiungere una nuova pagina ASP.NET alla BinaryData
cartella denominata DisplayCategoryPicture.aspx
. In questo caso, lasciare deselezionata la casella di controllo Seleziona pagina master. Questa pagina prevede un CategoryID
valore nella stringa di query e restituisce i dati binari della colonna della Picture
categoria. Poiché questa pagina restituisce dati binari e nient'altro, non è necessario alcun markup nella sezione HTML. Di conseguenza, fare clic sulla scheda Origine nell'angolo inferiore sinistro e rimuovere tutto il markup della pagina, ad eccezione della <%@ Page %>
direttiva . Ovvero, DisplayCategoryPicture.aspx
il markup dichiarativo deve essere costituito da una singola riga:
<%@ Page Language="VB" AutoEventWireup="true"
CodeFile="DisplayCategoryPicture.aspx.vb"
Inherits="BinaryData_DisplayCategoryPicture" %>
Se viene visualizzato l'attributo MasterPageFile
nella <%@ Page %>
direttiva , rimuoverlo.
Nella classe code-behind della pagina aggiungere il codice seguente al Page_Load
gestore eventi:
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
Questo codice inizia leggendo il valore querystring CategoryID
in una variabile denominata categoryID
. Successivamente, i dati dell'immagine vengono recuperati tramite una chiamata al CategoriesBLL
metodo della classe.GetCategoryWithBinaryDataByCategoryID(categoryID)
Questi dati vengono restituiti al client usando il Response.BinaryWrite(data)
metodo , ma prima di chiamare questo metodo, è necessario rimuovere l'intestazione Picture
OLE del valore della colonna. Questa operazione viene eseguita creando una Byte
matrice denominata strippedImageData
che conterrà esattamente 78 caratteri inferiori a quelli contenuti nella Picture
colonna. Il Array.Copy
metodo viene usato per copiare i dati dalla category.Picture
posizione 78 a strippedImageData
.
La Response.ContentType
proprietà specifica il tipo MIME del contenuto restituito in modo che il browser sappia come eseguirne il rendering. Poiché la Categories
colonna della Picture
tabella è un'immagine bitmap, viene usato qui il tipo MIME bitmap (image/bmp). Se si omette il tipo MIME, la maggior parte dei browser visualizzerà comunque l'immagine correttamente perché può dedurre il tipo in base al contenuto dei dati binari del file di immagine. Tuttavia, è prudente includere il tipo MIME quando possibile. Per un elenco completo dei tipi di supporti MIME, vedere il sito Web di Internet Assigned Numbers Authority s.
Con questa pagina creata, è possibile visualizzare un'immagine di una categoria specifica visitando DisplayCategoryPicture.aspx?CategoryID=categoryID
. La figura 11 mostra l'immagine della categoria Bevande, che può essere visualizzata da DisplayCategoryPicture.aspx?CategoryID=1
.
Figura 11: Viene visualizzata l'immagine della categoria bevande (fare clic per visualizzare l'immagine a dimensione intera)
Se, quando si visita DisplayCategoryPicture.aspx?CategoryID=categoryID
, si ottiene un'eccezione che legge Unable to cast object of type 'System.DBNull' to type 'System.Byte[]', there are two things that be cause this. In primo luogo, la Categories
colonna della Picture
tabella consente NULL
valori. La DisplayCategoryPicture.aspx
pagina, tuttavia, presuppone che esista un valore nonNULL
presente. Non Picture
è possibile accedere direttamente alla CategoriesDataTable
proprietà di se ha un NULL
valore. Se si desidera consentire NULL
i valori per la Picture
colonna, è necessario includere la condizione seguente:
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
Il codice precedente presuppone che nella cartella sia presente un file di immagine denominato NoPictureAvailable.gif
Images
che si desidera visualizzare per tali categorie senza un'immagine.
Questa eccezione può anche essere causata se l'istruzione CategoriesTableAdapter
s del metodo s GetCategoryWithBinaryDataByCategoryID
SELECT
è stata ripristinata all'elenco di colonne della query principale, che può verificarsi se si usano istruzioni SQL ad hoc ed è stata rieseguata la procedura guidata per la query principale di TableAdapter. Verificare che l'istruzione GetCategoryWithBinaryDataByCategoryID
del SELECT
metodo includa ancora la Picture
colonna .
Nota
Ogni volta che viene visitato, viene eseguito l'accesso DisplayCategoryPicture.aspx
al database e vengono restituiti i dati dell'immagine della categoria specificata. Se l'immagine della categoria non è stata modificata dopo l'ultima visualizzazione dell'utente, tuttavia, questo è uno spreco di lavoro. Fortunatamente, HTTP consente get condizionali. Con get condizionale, il client che effettua la richiesta HTTP invia lungo un'intestazione If-Modified-Since
HTTP che fornisce la data e l'ora dell'ultimo recupero della risorsa dal server Web. Se il contenuto non è stato modificato dopo questa data specificata, il server Web può rispondere con un codice di stato non modificato (304) e inviare nuovamente il contenuto della risorsa richiesta. In breve, questa tecnica evita al server Web di dover inviare contenuto per una risorsa se non è stato modificato dall'ultimo accesso al client.
Per implementare questo comportamento, tuttavia, è necessario aggiungere una PictureLastModified
colonna alla Categories
tabella da acquisire quando la Picture
colonna è stata aggiornata per l'ultimo aggiornamento, nonché il codice per verificare la presenza dell'intestazione If-Modified-Since
. Per altre informazioni sull'intestazione e sul flusso di lavoro GET condizionale, vedere HTTP Conditional GET for RSS Hackers (GET condizionale HTTP per hacker RSS) e Un'analisi più approfondita dell'esecuzione If-Modified-Since
di richieste HTTP in una pagina di ASP.NET.
Passaggio 4: Visualizzazione delle immagini di categoria in un controllo GridView
Ora che è disponibile una pagina Web per visualizzare un'immagine di una categoria specifica, è possibile visualizzarla usando il controllo Web Image o un elemento HTML <img>
che punta a DisplayCategoryPicture.aspx?CategoryID=categoryID
. Le immagini il cui URL è determinato dai dati del database possono essere visualizzate in GridView o DetailsView usando ImageField. ImageField contiene DataImageUrlField
proprietà e DataImageUrlFormatString
che funzionano come le proprietà e DataNavigateUrlFormatString
di DataNavigateUrlFields
HyperLinkField.
È possibile aumentare GridView Categories
in DisplayOrDownloadData.aspx
aggiungendo un oggetto ImageField per visualizzare l'immagine di ogni categoria. È sufficiente aggiungere ImageField e impostarne DataImageUrlField
le proprietà e DataImageUrlFormatString
rispettivamente su CategoryID
e DisplayCategoryPicture.aspx?CategoryID={0}
. Verrà creata una colonna GridView che esegue il rendering di un <img>
elemento il cui src
attributo fa riferimento DisplayCategoryPicture.aspx?CategoryID={0}
a , dove {0} viene sostituito con il valore della CategoryID
riga gridView.
Figura 12: Aggiungere un oggetto ImageField a GridView
Dopo aver aggiunto ImageField, la sintassi dichiarativa di GridView dovrebbe essere simile alla seguente:
<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>
Dedicare un attimo alla visualizzazione di questa pagina tramite un browser. Si noti che ogni record include ora un'immagine per la categoria.
Figura 13: Viene visualizzata l'immagine della categoria per ogni riga (fare clic per visualizzare l'immagine a dimensione intera)
Riepilogo
In questa esercitazione è stato esaminato come presentare i dati binari. La modalità di presentazione dei dati dipende dal tipo di dati. Per i file di brochure PDF, abbiamo offerto all'utente un collegamento View Brochure che, quando si fa clic, ha portato l'utente direttamente al file PDF. Per l'immagine della categoria, è stata creata prima una pagina per recuperare e restituire i dati binari dal database e quindi è stata usata tale pagina per visualizzare l'immagine di ogni categoria in un controllo GridView.
Ora che è stato esaminato come visualizzare i dati binari, è possibile esaminare come eseguire inserimento, aggiornamenti ed eliminazioni nel database con i dati binari. Nell'esercitazione successiva verrà illustrato come associare un file caricato al record di database corrispondente. Nell'esercitazione successiva verrà illustrato come aggiornare i dati binari esistenti e come eliminare i dati binari quando viene rimosso il record associato.
Buon programmatori!
Informazioni sull'autore
Scott Mitchell, autore di sette libri ASP/ASP.NET e fondatore di 4GuysFromRolla.com, ha lavorato con le tecnologie Web Microsoft dal 1998. Scott lavora come consulente indipendente, formatore e scrittore. Il suo ultimo libro è Sams Teach Yourself ASP.NET 2.0 in 24 ore. Può essere raggiunto all'indirizzo mitchell@4GuysFromRolla.com. o tramite il suo blog, che può essere trovato all'indirizzo http://ScottOnWriting.NET.
Grazie speciale a
Questa serie di esercitazioni è stata esaminata da molti revisori utili. I revisori principali per questa esercitazione erano Teresa Murphy e Dave Gardner. Si è interessati a esaminare i prossimi articoli MSDN? In tal caso, rilasciarmi una riga in mitchell@4GuysFromRolla.com.