Condividi tramite


Visualizzazione di dati binari nei controlli Web dei dati (VB)

di Scott Mitchell

Scarica il PDF

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 associare i dati binari a un modello di dati sottostante di un'applicazione e si è usato 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 il caricamento e il salvataggio di un file 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. Presentare 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, Microsoft Word documenti, 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: SpecificareBrochurePathi 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, granulare e di bassa qualità. Ogni immagine di categoria è larga 172 pixel 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 di 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 accedere a 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. Pertanto, è 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 specificare manualmente i valori per questa colonna.

In questa esercitazione sono disponibili sette file di brochure PDF nella ~/Brochures cartella, uno per ognuna delle categorie, ad eccezione di Seafood. Ho omesso intenzionalmente di aggiungere una brochure di 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 Categories mouse sul 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 è presente una brochure per la categoria Frutti di mare, lasciare il BrochurePath valore della colonna come NULL.

Immettere manualmente i valori per la colonna BrochurePath della tabella Categories

Figura 1: Immettere manualmente i valori per la Categories colonna della BrochurePath tabella (fare clic per visualizzare l'immagine a dimensione intera)

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 si estenderà questo controllo GridView per visualizzare anche l'immagine della categoria.

Per iniziare, trascinare un controllo GridView dalla casella degli strumenti nella Designer 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 CategoriesBLLGetCategories() .

Creare un nuovo oggettoDataSource denominato CategoriesDataSource

Figura 2: Creare un nuovo oggettoDataSource denominato CategoriesDataSource (fare clic per visualizzare l'immagine a dimensione intera)

Configurare ObjectDataSource per l'uso della classe CategoriesBLL

Figura 3: Configurare ObjectDataSource per l'uso della classe (fare clic per visualizzare l'immagineCategoriesBLL a dimensione intera)

Recuperare l'elenco di categorie utilizzando il metodo GetCategories()

Figura 4: Recuperare l'elenco delle categorie usando 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 BoundField a Categories GridView per CategoryID, CategoryName, NumberOfProductsDescription, e BrochurePathDataColumn s. Procedere e rimuovere BoundField NumberOfProducts perché la GetCategories() query del metodo non recupera queste informazioni. Rimuovere inoltre le CategoryID proprietà BoundField e rinominare le CategoryName proprietà BoundFields BrochurePathHeaderText rispettivamente in 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. Frutti di mare, che ha un NULL valore per , BrochurePathvisualizza una cella vuota.

Ogni nome, descrizione e valore BrochurePath di ogni categoria è elencato

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 hyperLinkField. Impostare la nuova proprietà HyperLinkField su HeaderText Brochure, la relativa Text proprietà su View Brochure e la relativa DataNavigateUrlFields proprietà su BrochurePath.

Aggiungere un HyperLinkField per BrochurePath

Figura 6: Aggiungere un campo HyperLink 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 verrà richiesto all'utente di scaricare il file, a seconda che sia installato un lettore PDF e le impostazioni del browser.

È possibile visualizzare una brochure di categoria facendo clic sul collegamento Visualizza brochure

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)

Il PDF della brochure della categoria è visualizzato

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 brochure

Come illustrato nella figura 7, HyperLinkField visualizza il BrochurePath valore Text della proprietà ( Visualizza brochure ) per tutti i record, indipendentemente dal fatto che sia presente un valore diversoNULL da per BrochurePath. Naturalmente, se BrochurePath è NULL, il collegamento viene visualizzato solo come testo, come nel caso della categoria Frutti di mare (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 per la prima volta 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 della finestra di dialogo Modifica colonne.

Convertire HyperLinkField in un campo template

Figura 9: Convertire HyperLinkField in un campo modello

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 un String oggetto e accetta come Object 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 Frutti di mare BrochurePath visualizza ora il testo No Brochure Available .

Il testo nessun opuscolo disponibile è visualizzato per tali categorie senza brochure

Figura 10: Il testo non è disponibile brochure 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 di 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 segue:

<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 di cui è stato eseguito il rendering fornisce 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 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 querystring 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. Fare quindi 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 CategoryID valore querystring in una variabile denominata categoryID. Successivamente, i dati 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 della chiamata, è necessario rimuovere l'intestazione OLE del Picture 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à 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 dell'Autorità numeri assegnati da Internet.

Dopo aver creato questa pagina, è 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.

L'immagine della categoria bevande è visualizzata

Figura 11: Immagine della categoria bevande visualizzata (fare clic per visualizzare l'immagine a dimensione intera)

Se, quando si visita DisplayCategoryPicture.aspx?CategoryID=categoryID, viene visualizzata un'eccezione che legge Impossibile eseguire il cast dell'oggetto di tipo "System.DBNull" per digitare "System.Byte[]", sono presenti due elementi che potrebbero causare questo problema. 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 sia presente un file di immagine denominato NoPictureAvailable.gif nella Images cartella che si desidera visualizzare per tali categorie senza un'immagine.

Questa eccezione può essere causata anche se l'istruzione CategoriesTableAdapter del metodo s GetCategoryWithBinaryDataByCategoryIDSELECT è stata ripristinata all'elenco di colonne della query principale, che può verificarsi se si usano istruzioni SQL ad hoc ed è stata rieseguita 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 immagine della categoria specificati. Se l'immagine della categoria non è stata modificata dopo l'ultima visualizzazione dell'utente, tuttavia, questa operazione è sprecata. Fortunatamente, HTTP consente get condizionali. Con un get condizionale, il client che effettua la richiesta HTTP invia lungo un'intestazioneIf-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 consente al server Web di non dover inviare contenuto per una risorsa se non è stato modificato dall'ultimo accesso del 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 e 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 Hacker e Un'analisi più approfondita sull'esecuzione di richieste HTTP in una pagina di ASP.NET.If-Modified-Since

Passaggio 4: Visualizzazione delle immagini di categoria in un controllo GridView

Ora che è disponibile una pagina Web per visualizzare un'immagine di una determinata categoria, è 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 hyperLinkFieldDataNavigateUrlFields.

È possibile aumentare Categories GridView in DisplayOrDownloadData.aspx aggiungendo un oggetto ImageField per visualizzare l'immagine di ogni categoria. È sufficiente aggiungere ImageField e impostarne le DataImageUrlField 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 DisplayCategoryPicture.aspx?CategoryID={0}riferimento a , dove {0} viene sostituito con il valore della riga gridView CategoryID .

Aggiungere un oggetto ImageField a 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 qualche minuto alla visualizzazione di questa pagina tramite un browser. Si noti che ogni record include ora un'immagine per la categoria.

L'immagine della categoria viene visualizzata per ogni riga

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 dati binari. La modalità di presentazione dei dati dipende dal tipo di dati. Per i file della 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.

Dopo aver 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 il record associato viene rimosso.

Buon programmatori!

Informazioni sull'autore

Scott Mitchell, autore di sette libri ASP/ASP.NET e fondatore di 4GuysFromRolla.com, lavora 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, disponibile 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, rilasciami una riga in mitchell@4GuysFromRolla.com.