Esercitazione 4: Visualizzazione dei dati con ObjectDataSource

Scott Mitchell

Giugno 2006

Scarica l'esempio di codice ASPNET_Data_Tutorial_4_CS.exe.

Sommario dell'esercitazione 4 (Visual C#)

Introduzione
Passaggio 1: Inserimento e configurazione del controllo ObjectDataSource
Passaggio 2: Inserimento e associazione di un controllo Web per dati a ObjectDataSource
Utilizzo dei temi per garantire un aspetto coerente
Visualizzazione di un record alla volta in DetailsView
Riepilogo

Introduzione

Avendo completato l'architettura della nostra applicazione e il layout di pagina del sito Web, possiamo ora affrontare varie attività relative ai dati comuni e ai report. Nelle esercitazioni precedenti abbiamo visto come associare programmaticamente i dati DAL (Data Access Layer) e BLL (Business Logic Layer) a un controllo Web per dati in una pagina ASP.NET. La sintassi utilizzata nelle applicazioni ASP.NET 1.x – che consisteva nell'assegnazione della proprietà DataSource del controllo Web ai dati da visualizzare seguita dalla chiamata al metodo DataBind() del controllo – può essere utilizzata anche nelle applicazioni 2.0. I nuovi controlli origine dati di ASP.NET 2.0 offrono però un nuovo metodo dichiarativo per l'utilizzo dei dati. Con questi controlli è possibile associare i dati recuperati dalla classe BLL creata nell'esercitazione precedente senza dover scrivere una sola riga di codice.

ASP.NET 2.0 rende disponibili cinque controlli origine dati incorporati – SqlDataSource, AccessDataSource, ObjectDataSource, XmlDataSource e SiteMapDataSource – e consente di creare controlli origine dati personalizzati, se necessario. Poiché abbiamo sviluppato un'architettura per l'applicazione della nostra esercitazione, utilizzeremo ObjectDataSource per le nostre classi BLL.

Figura 1. ASP.NET 2.0 include cinque controlli origine dati incorporati

ObjectDataSource funge da proxy per altri oggetti. Per configurare ObjectDataSource, specifichiamo l'oggetto sottostante e mappiamo i metodi di questo oggetto ai metodi Select, Insert, Update e Delete di ObjectDataSource. Dopo aver specificato l'oggetto sottostante e mappato i suoi metodi ai metodi di ObjectDataSource, possiamo associare ObjectDataSource a un controllo Web per dati. ASP.NET dispone di molti controlli Web per dati, compresi, tra gli altri, GridView, DetailsView, RadioButtonList e DropDownList. Durante il ciclo di vita della pagina, il controllo Web per dati può dover accedere ai dati a cui è associato e questa operazione può essere eseguita richiamando il metodo Select di ObjectDataSource; se il controllo Web per dati supporta l'inserimento, l'aggiornamento e l'eliminazione di dati, è possibile richiamare i metodi Insert, Update o Delete di ObjectDataSource. Queste chiamate vengono poi indirizzate da ObjectDataSource ai metodi appropriati dell'oggetto sottostante, come illustrato nel diagramma seguente.

Figura 2. ObjectDataSource funge da proxy

Abbiamo visto che ObjectDataSource può essere utilizzato per richiamare i metodi per l'inserimento, l'aggiornamento o l'eliminazione dei dati, ma in questa sede vogliamo soffermarci sui dati restituiti; l'utilizzo di ObjectDataSource e dei controlli Web per la modifica dei dati verranno esaminati nelle esercitazioni successive.

Passaggio 1: Inserimento e configurazione del controllo ObjectDataSource

Aprire la pagina SimpleDisplay.aspx nella cartella BasicReporting, passare alla visualizzazione Struttura e quindi trascinare un controllo ObjectDataSource dalla Casella degli strumenti sull'area di progettazione della pagina. ObjectDataSource ha l'aspetto di un riquadro grigio nell'area di progettazione perché non produce alcun markup; accede semplicemente ai dati richiamando un metodo di un oggetto specificato. I dati restituiti da ObjectDataSource possono essere visualizzati da un controllo Web per dati, ad esempio GridView, DetailsView, FormView e così via.

Nota   In alternativa, è possibile aggiungere dapprima il controllo Web alla pagina e poi, dal suo smart tag, scegliere l'opzione <Nuova origine dati> nell'elenco a discesa.

Per specificare l'oggetto sottostante di ObjectDataSource e mappare i metodi di questo oggetto a quelli di ObjectDataSource, fare clic sul collegamento Configura origine dati nello smart tag di ObjectDataSource.

Figura 3. Fare clic sul collegamento Configura origine dati nello smart tag

Verrà visualizzata la procedura guidata Configura origine dati. Innanzitutto, dobbiamo specificare l'oggetto con cui ObjectDataSource deve lavorare. Se la casella di controllo "Mostra solo componenti dati" è selezionata, nell'elenco a discesa di questa schermata sono riportati solo gli oggetti che hanno ricevuto l'attributo DataObject. Attualmente il nostro elenco include i TableAdapter del dataset tipizzato e le classi BLL che abbiamo creato nell'esercitazione precedente. Se ci si è dimenticati di aggiungere l'attributo DataObject alle classi BLL (Business Logic Layer), queste classi non saranno visualizzate in questo elenco. In tal caso, deselezionare la casella di controllo "Mostra solo componenti dati" per visualizzare l'elenco di tutti gli oggetti, che dovrebbe includere le classi BLL (assieme alle altre classi del dataset tipizzato, ossia DataTable, DataRow e così via).

Nella prima schermata, scegliere la classe ProductsBLL dall'elenco a discesa e fare clic su Avanti.

Figura 4. Specificare l'oggetto da utilizzare con il controllo ObjectDataSource

Nella schermata successiva della procedura guidata viene chiesto di selezionare il metodo che ObjectDataSource deve richiamare. L'elenco a discesa visualizza i metodi che restituiscono dati per l'oggetto selezionato nella schermata precedente. I metodi sono GetProductsByProductID, GetProducts, GetProductsByCategoryID e GetProductsBySupplierID. Selezionare il metodo GetProducts dall'elenco a discesa e fare clic su Fine (se è stato aggiunto DataObjectMethodAttribute ai metodi di ProductBLL, come mostrato nell'esercitazione precedente, questa opzione sarà selezionata per impostazione predefinita).

Figure 5. Scegliere il metodo per la restituzione dei dati nella scheda SELEZIONA

Configurazione manuale di ObjectDataSource

La procedura guidata Configura origine dati di ObjectDataSource costituisce un metodo rapido per specificare l'oggetto da utilizzare e per associarlo ai metodi dell'oggetto da richiamare. È comunque possibile configurare ObjectDataSource mediante le sue proprietà, utilizzando la finestra Proprietà o direttamente nel markup dichiarativo. Impostare semplicemente la proprietà TypeName sul tipo di oggetto sottostante da utilizzare e il metodo SelectMethod sul metodo da richiamare al momento del recupero dei dati.

<asp:ObjectDataSource ID="ObjectDataSource1" runat="server" 
        SelectMethod="GetProducts"
        TypeName="ProductsBLL">
</asp:ObjectDataSource>

Anche se si preferisce la procedura guidata Configura origine dati, talvolta potrebbe essere necessario configurare manualmente ObjectDataSource, poiché la procedura guida elenca solo le classi create dallo sviluppatore. Se si desidera associare ObjectDataSource a una classe di .NET Framework – ad esempio alla classe appartenenza, per accedere alle informazioni degli account utente, o alla classe directory per utilizzare le informazioni del file system – sarà necessario impostare manualmente le proprietà di ObjectDataSource.

Passaggio 2: Inserimento e associazione di un controllo Web per dati a ObjectDataSource

Dopo aver inserito ObjectDataSource nella pagina e averlo configurato, possiamo aggiungere alla pagina controlli Web per dati per visualizzare i dati restituiti dal metodo Select di ObjectDataSource. Qualsiasi controllo Web per dati può essere associato a ObjectDataSource; spiegherò ora come visualizzare i dati di ObjectDataSource in un controllo GridView, DetailsView e FormView.

Associazione di un controllo GridView a ObjectDataSource

Aggiungere un controllo GridView dalla Casella degli strumenti all'area di progettazione di SimpleDisplay.aspx. Nello smart tag di GridView, scegliere il controllo ObjectDataSource aggiunto al Passaggio 1. In questo modo, verrà creato automaticamente un BoundField in GridView per ciascuna proprietà restituita dai dati del metodo Select di ObjectDataSource (nello specifico, le proprietà definite nel DataTable dei prodotti).

Figura 6. Un controllo GridView è stato inserito nella pagina e associato a ObjectDataSource

È quindi possibile personalizzare, ridisporre e rimuovere i BoundField di GridView facendo clic sull'opzione Modifica colonne dello smart tag.

Figura 7. Gestire i BoundField di GridView mediante la finestra di dialogo Modifica colonne

Modificare i BoundField di GridView rimuovendo i BoundField ProductID, SupplierID, CategoryID, QuantityPerUnit, UnitsInStock, UnitsOnOrder e ReorderLevel. Selezionare semplicemente i BoundField dall'elenco nell'angolo inferiore sinistro e fare clic sul pulsante di eliminazione (contrassegnato con una X rossa) per rimuoverli. Ridisporre i BoundField in modo che i BoundField CategoryName e SupplierName precedano UnitPrice selezionando questi BoundField e facendo clic sulla freccia in su. Impostare le proprietà HeaderText dei restanti BoundField rispettivamente su Products, Category, Supplier e Price. Formattare quindi il BoundField Price come valuta impostando la proprietà HtmlEncode del BoundField su False e la proprietà DataFormatString su {0:c}. Infine, allineare orizzontalmente il prezzo (Price) a destra e la casella di controllo degli articoli non più in produzione (Discontinued) al centro mediante la proprietà ItemStyle/HorizontalAlign.

<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False"    
                                DataKeyNames="ProductID" DataSourceID="ObjectDataSource1" 
                                EnableViewState="False">
    <Columns>
        <asp:BoundField DataField="ProductName" HeaderText="Product" 
        SortExpression="ProductName" />
        <asp:BoundField DataField="CategoryName" HeaderText="Category" 
        ReadOnly="True" SortExpression="CategoryName" />
        <asp:BoundField DataField="SupplierName" HeaderText="Supplier" 
        ReadOnly="True" SortExpression="SupplierName" />
        <asp:BoundField DataField="UnitPrice" DataFormatString="{0:c}" 
        HeaderText="Price"
            HtmlEncode="False" SortExpression="UnitPrice">
            <ItemStyle HorizontalAlign="Right" />
        </asp:BoundField>
        <asp:CheckBoxField DataField="Discontinued" HeaderText="Discontinued" 
        SortExpression="Discontinued">
            <ItemStyle HorizontalAlign="Center" />
        </asp:CheckBoxField>
    </Columns>
</asp:GridView>

Figura 8. I BoundField di GridView sono stati personalizzati

Utilizzo dei temi per garantire un aspetto coerente

In queste esercitazioni cercheremo di rimuovere tutte le impostazioni di stile a livello di controllo e di utilizzare invece, ove possibile, i fogli di stile CSS definiti in un file esterno. Il file Styles.css contiene le classi CSS DataWebControlStyle, HeaderStyle, RowStyle e AlternatingRowStyle, che dovrebbero essere utilizzate per determinare l'aspetto dei controlli Web utilizzati in queste esercitazioni. A tal fine, possiamo impostare la proprietà CssClass di GridView su DataWebControlStyle e le altre proprietà CssClass su HeaderStyle, RowStyle e AlternatingRowStyle, a seconda delle esigenze.

Se impostassimo queste proprietà CssClass a livello del controllo Web dovremmo ricordarci di impostare esplicitamente i valori di queste proprietà per ciascun controllo Web che aggiungiamo di volta in volta nel corso delle esercitazioni. Un metodo più semplice consiste nel definire le proprietà CSS predefinite per i controlli GridView, DetailsView e FormView utilizzando un tema. Un tema è un insieme di impostazioni relative alle proprietà dei controlli, immagini e classi CSS che possono essere applicate alle pagine di un sito per garantire un aspetto comune e coerente.

Il nostro tema non includerà nessuna immagine o file CSS (lasceremo il foglio di stile Styles.css così com'è, nella cartella principale dell'applicazione Web), ma includerà due interfacce. Un'interfaccia è un file che definisce le proprietà predefinite di un controllo Web. Nello specifico, avremo un file di interfaccia per il controllo GridView e uno per DetailsView, che definiscono le proprietà predefinite relative a CssClass.

Iniziamo con l'aggiungere al nostro progetto un nuovo file di interfaccia denominato GridView.skin facendo clic con il pulsante destro del mouse sul nome del progetto in Esplora soluzioni e scegliendo Aggiungi nuovo elemento.

Figura 9. Aggiungere un nuovo file di interfaccia denominato GridView.skin

I file di interfaccia devono essere inseriti in un tema; i temi devono trovarsi nella cartella App_Themes. Poiché non abbiamo ancora questa cartella, Visual Studio chiederà di crearne una in automatico quando si aggiunge la prima interfaccia. Scegliere Sì per creare la cartella App_Theme e inserirvi il nuovo file GridView.skin.

Figura 10. Scegliere Sì per fare in modo che Visual Studio creo la cartella App_Theme in automatico

Verrà creato un nuovo tema nella cartella App_Themes denominato GridView con il file di interfaccia GridView.skin.

Figura 11. Il tema GridView è stato aggiunto alla cartella App_Theme

Rinominare il tema GridView in DataWebControls (fare clic con il pulsante destro del mouse sulla cartella GridView nella cartella App_Theme e scegliere Rinomina). Inserire quindi il seguente markup nel file GridView.skin:


<asp:GridView runat="server" CssClass="DataWebControlStyle">
   <AlternatingRowStyle CssClass="AlternatingRowStyle" />
   <RowStyle CssClass="RowStyle" />
   <HeaderStyle CssClass="HeaderStyle" />   
</asp:GridView>


Questo markup definisce le proprietà relative a CssClass per tutti i GridView in tutte le pagine che utilizzano il tema DataWebControls. Aggiungiamo ora un'altra interfaccia per il controllo Web DetailsView, che utilizzeremo tra breve. Aggiungere un'altra interfaccia al tema DataWebControls denominata DetailsView.skin e inserire il seguente markup:

<asp:DetailsView runat="server" CssClass="DataWebControlStyle">
   <AlternatingRowStyle CssClass="AlternatingRowStyle" />
   <RowStyle CssClass="RowStyle" />
   <FieldHeaderStyle CssClass="HeaderStyle" />
</asp:DetailsView>

Dopo aver definito il nostro tema, l'ultima operazione da fare è applicare il tema alla nostra pagina ASP.NET. Un tema può essere applicato pagina per pagina o a tutte le pagine di un sito Web. In questa sede, vogliamo utilizzare questo tema per tutte le pagine del sito Web. Per farlo, aggiungere il seguente markup alla sezione <system.web> di Web.config:

<pages styleSheetTheme="DataWebControls" />

Ecco fatto! L'impostazione styleSheetTheme indica che le proprietà specificate nel tema non devono escludere le proprietà specificate a livello del controllo. Per specificare che le impostazioni del tema non devono escludere le impostazioni del controllo, utilizzare l'attributo theme invece di styleSheetTheme; sfortunatamente, le impostazioni del tema specificate mediante l'attributo theme non vengono visualizzate nella visualizzazione Struttura di Visual Studio. Per ulteriori informazioni su temi e interfacce, vedere Cenni preliminari su temi e interfacce ASP.NET e Server-Side Styles Using Themes (in inglese); per ulteriori informazioni sulla configurazione di una pagina per l'utilizzo di un tema, vedere Procedura: applicare temi ASP.NET.

Figura 12. GridView visualizza le informazioni Product (Nome prodotto), Category (Categoria), Supplier (Fornitore), Price (Prezzo) e Discontinued (Fuori produzione)

Visualizzazione di un record alla volta in DetailsView

GridView visualizza una riga per ogni record restituito dal controllo origine dati al quale è associato. A volte, tuttavia, potrebbe essere necessario visualizzare un solo record o un record per volta. Il controllo DetailsView offre una funzionalità che trasforma i dati visualizzati in una tabella (<table>) HTML con due colonne e una riga per ciascuna colonna o proprietà associata al controllo. In questi casi, è possibile pensare a DetailsView come a un GridView con un solo record ruotato di 90°.

Iniziamo con l'aggiungere un controllo DetailsView sopra GridView in SimpleDisplay.aspx. Associamolo quindi allo stesso controllo ObjectDataSource di GridView. Come in GridView, in DetailsView verrà inserito un BoundField per ciascuna proprietà dell'oggetto restituita dal metodo Select di ObjectDataSource. La sola differenza è che i BoundField di DetailsView sono disposti orizzontalmente e non verticalmente.

Figure 13. Inserire un controllo DetailsView nella pagina e associarlo a ObjectDataSource

Come per GridView, i BoundField di DetailsView possono essere modificati per fornire una visualizzazione più personalizzata dei dati restituiti da ObjectDataSource. La figura 14 mostra DetailsView dopo che sono stati configurati i BoundField e le proprietà CssClass per rendere l'aspetto del controllo più simile all'esempio GridView.

Figura 14. DetailsView mostra un solo record

Si osservi che DetailsView visualizza solo il primo record restituito dall'origine dati. Per far sì che l'utente possa scorrere i record uno alla volta, è necessario attivare il paging in DetailsView. Per farlo, tornare a Visual Studio e selezionare la casella di controllo Attiva paging nello smart tag di DetailsView.

Figura 15. Opzione Attiva paging per il controllo DetailsView

Figura 16. Con il paging attivato, DetailsView consente all'utente di visualizzare tutti i prodotti

Nelle esercitazioni successive ci soffermeremo maggiormente sulla funzione di paging.

Un layout più flessibile per visualizzare un record alla volta

Il controllo DetailsView è alquanto rigido nel modo in cui visualizza ciascun record restituito da ObjectDataSource. Talvolta potremmo desiderare una visualizzazione più flessibile dei dati. Ad esempio, invece di mostrare ciascuna informazione di nome prodotto, categoria, fornitore, prezzo e fuori produzione in una riga a sé, potremmo voler mostrare il nome del prodotto e il prezzo in un'intestazione <h2>, con le informazioni sulla categoria e il fornitore sotto il nome e il prezzo riportate in caratteri più piccoli. E potremmo non voler visualizzare i nomi delle proprietà (prodotto, categoria, ecc.) accanto ai valori.

Il controllo FormView offre questo livello di personalizzazione. Piuttosto che utilizzare campi (come fanno GridView e DetailsView), FormView utilizza modelli che consentono di avvalersi contemporaneamente di controlli Web, HTML statico e sintassi di associazione dati. Se si ha dimestichezza con il controllo Repeater di ASP.NET 1.x, si pensi a FormView come a un Repeater che consente di visualizzare un solo record.

Inserire un controllo FormView nell'area di progettazione della pagina SimpleDisplay.aspx. L'aspetto iniziale di FormView è quello di un riquadro grigio, che serve a informarci che dobbiamo fornire almeno il modello ItemTemplate del controllo.

Figura 17. FormView deve contenere un ItemTemplate

È possibile associare FormView direttamente a un controllo origine dati tramite lo smart tag di FormView, che creerà automaticamente un modello ItemTemplate predefinito (assieme a un EditItemTemplate e InsertItemTemplate, se sono impostate le proprietà InsertMethod e UpdateMethod del controllo ObjectDatatSource). In questo esempio, però, assoceremo i dati a FormView e specifichiamo manualmente il modello ItemTemplate. Iniziamo con l'impostare la proprietà DataSourceID di FormView sull'ID del controllo ObjectDataSource, ObjectDataSource1. Creiamo quindi il modello ItemTemplate in modo che visualizzi il nome del prodotto e il prezzo in un elemento <h2> e i nomi della categoria e del fornitore sotto questo elemento in caratteri più piccoli.

<asp:FormView ID="FormView1" runat="server" DataSourceID="ObjectDataSource1" EnableViewState="False">
    <ItemTemplate>
        <h2><%# Eval("ProductName") %> (<%# Eval("UnitPrice", "{0:c}") %>)</h2>
        Category: <%# Eval("CategoryName") %>; Supplier: <%# Eval("SupplierName") %>
    </ItemTemplate>
</asp:FormView>

Figura 18. Il primo prodotto (Chai) è visualizzato in un formato personalizzato

<%# Eval(propertyName) %> è la sintassi di associazione dati. Il metodo Eval restituisce il valore della proprietà specificata per l'oggetto attualmente associato al controllo FormView. Per ulteriori informazioni sui vantaggi e gli svantaggi dell'associazione dati, vedere l'articolo di Alex Homer Simplified and Extended Data Binding Syntax in ASP.NET 2.0 (in inglese).

Analogamente a DetailsView, FormView mostra solo il primo record restituito da ObjectDataSource. È possibile attivare il paging in FormView per consentire agli utenti di scorrere i prodotti uno alla volta.

Riepilogo

È ora possibile accedere e visualizzare i dati di una classe BLL (Business Logic Layer) senza scrivere una riga di codice grazie al controllo ObjectDataSource di ASP.NET 2.0. ObjectDataSource richiama un metodo specifico di una classe e restituisce i risultati. Questi risultati possono essere visualizzati in un controllo Web per dati associato a ObjectDataSource. In questa esercitazione abbiamo imparato ad associare i controlli GridView, DetailsView e FormView a ObjectDataSource.

Finora abbiamo visto solo come si può utilizzare ObjectDataSource per richiamare un metodo privo di parametri, ma cosa succederebbe se volessimo richiamare un metodo che prevede parametri di input, come GetProductsByCategoryID(categoryID) della classe ProductBLL? Per richiamare un metodo che prevede uno o più parametri, dobbiamo configurare ObjectDataSource per specificare i valori per questi parametri. Affronteremo questo argomento nell'esercitazione successiva.

Buona programmazione!

Altre letture

Per ulteriori informazioni sugli argomenti discussi in questa esercitazione, consultare le seguenti risorse:

 

Informazioni sull'autore

Autore di sei libri su ASP/ASP.NET e fondatore di 4GuysFromRolla.com, Scott Mitchell collabora allo sviluppo delle tecnologie Web di Microsoft dal 1998. Scott lavora per Microsoft come consulente, insegnante di corsi di formazione e autore freelance. Recentemente ha terminato il suo ultimo libro, Sams Teach Yourself ASP.NET 2.0 in 24 Hours. È possibile contattarlo all'indirizzo mitchell@4guysfromrolla.com o sul suo blog all'indirizzo http://ScottOnWriting.NET.

Ringraziamenti speciali

Ringrazio i molti revisori di questa serie di esercitazioni che mi sono stati di grande aiuto. Ringrazio inoltre Hilton Giesenow, il revisore capo di questa esercitazione. Ti interessa rivedere i miei articoli di MSDN futuri? In caso affermativo, scrivimi all'indirizzo mitchell@4GuysFromRolla.com.

Mostra: