in

DotNetSide

Dot Net South Italy Developers User Group

Articoli

Articoli pubblicati dagli iscritti a .netSide

Il Web di nuova generazione: gestire efficacemente le nuove tecnologie .NET

Autori: Marco Maltraversi e Giulio Destri

Il Web oggi e le prospettive di evoluzione

A quasi venti anni dalla sua nascita come strumento per pochi al CERN di Ginevra e a quasi quindici dall’avvento del suo uso commerciale, il web oggi è una realtà che fa parte della vita di ogni giorno. E l’evoluzione del web continua: non solo il numero complessivo di siti cresce, ma le potenzialità tecnologiche evolvono rapidamente e più ricche sono le opportunità offerte agli utenti finali. Nascono nuovi software e servizi che estendono il web verso modelli più evoluti, in particolare per ciò che riguarda l’interfaccia utente, passata in questi anni dalle prime pagine statiche a applicazioni sempre più interattive.

In particolare è stato recentemente introdotto il concetto di Rich Internet Application (RIA), definendo con tale termine un insieme di applicazioni web che hanno caratteristiche e funzionalità del tutto equivalenti alle “tradizionali” applicazioni desktop (cioè residenti sul computer). Nelle RIA il browser, che deve elaborare le funzionalità dell’interfaccia utente e della presentazione dei dati, è chiamato a svolgere un compito ancora più importante. Questo approccio migliora l’interazione con il web, rendendola quasi indistinguibile da quella con i programmi desktop.

E’ stato coniato anche il termine esperienza utente (User Esperience) per indicare il complesso di esperienze ed il conseguente livello di soddisfazione che un utente ottiene nell’interagire con un’applicazione. Normalmente questo termine assume una connotazione positiva, indicando che l’utente trova più intuitivo e comodo l’uso dell’applicazione.

L’avvento delle RIA ha permesso agli sviluppatori di utilizzare funzionalità avanzate per le interfacce utente web, che rendono le applicazioni più semplici, utilizzabili e forniscono agli utilizzatori finali strumenti più produttivi, riducendo i tempi operativi e di navigazione necessari per l’interazione con le applicazioni stesse.

clip_image007

Esempio di interfaccia utente di applicativo RIA realizzato con Silverlight

Diverse sono le piattaforme tecnologiche che i vari vendor hanno proposto per realizzare questa nuova generazione di applicazioni web. In particolare in questo articolo saranno trattate le soluzioni proposte da Microsoft come estensioni della piattaforma ASP.NET ed integrate nella versione 3.5 del framework .NET.

Le novità del framework .NET 3.5

Microsoft ha sviluppato diversi nuovi componenti tecnologici orientati allo sviluppo rapido di applicazioni Web RIA. Per meglio capire la loro struttura è bene esaminare in una visione di insieme tutti i vari componenti della versione 3.5 aggiunti rispetto al core già presente nella 2.0:

  • XAML (eXtensible Application Markup Language) un linguaggio di markup basato su XML atto a descrivere struttura ed inizializzazione di insiemi di oggetti e convertibile (anche a run-time) in codice eseguibile;
  • WPF (Windows Presentation Foundation), un insieme completo di librerie per lo sviluppo di interfacce utente a oggetti, che usa internamente XAML per definire i componenti dell’interfaccia, il binding verso i dati, la gestione degli eventi ed altre caratteristiche;
  • XBAP, componente di WPF che consente il funzionamento di interfacce utente sviluppate in XAML anche entro un browser (Internet Explorer o Firefox), purchè sul PC che ospita il browser sia installato anche il framework .NET 3.5; il modello di XBAP è simile a quello degli applet Java basati sulle versioni più avanzate che si appoggiano sulla JVM installata nel sistema;
  • WCF (Windows Communication Foundation) implementa un insieme di funzioni per lo sviluppo di applicazioni distribuite ad oggetti e comprende al suo interno anche la tecnologia dei web service già presente nella versione 2.0 di .NET;
  • WF (Windows Workflow Foundation) , insieme di librerie per il workflow, atte a realizzare sistemi di gestione dei flussi delle attività e dei processi di business aziendali; anche i percorsi del workflow possono essere realizzati tramite XAML o scritti direttamente in codice C# o VB.NET;
  • Windows Card Space costrutto utilizzato per la memorizzazione e gestione dei diritti di accesso e dei profili;
  • LINQ (Integration of Language Integrated Query) è un estensione di tipo dichiarativo del linguaggio che premette la ricerca all'interno di qualunque struttura dati (per esempio database relazionali, file XML e strutture di oggetti presenti in memoria) sfruttando direttamente una sintassi “simil SQL”.

Sono state inoltre aggiunti nuovi componenti, in verità non proprio “inclusi” nel framework, come:

  • Silverlight, una struttura applicativa che permette di aggiungere funzionalità aggiuntive alle applicazioni web, come streaming, effetti grafici e animazioni; nella versione 1.1 correntemente disponibile viene usato un sottoinsieme di XAML per definire i componenti grafici e il linguaggio Javascript per gestire gli eventi, mentre la futura versione 2.0 dovrebbe consentire l’uso diretto di C# o VB.NET entro i componenti; il vantaggio di interfacce utente web sviluppate con Silverlight rispetto a XBAP è quello di non richiedere la presenza dell’intero framework .NET 3.5 sul PC ove opera il browser, ma solo del piccolo plug-in Silverlight, scaricabile rapidamente analogamente a quello di Flash;
  • Asp.NET AJAX libreria che aggiunge nuove funzionalità AJAX agli applicativi web e ne consente di migliorare l’interattività e l’efficienza; in particolare è possibile combinare efficacemente insieme Silverlight ed ASP.NET AJAX per ottenere il meglio di entrambi.

clip_image009

Figura 2: il framework .NET 3.5 come estensione del 2.0

Per potere efficacemente usare le tecnologie presentate, l’ambiente di sviluppo migliore è l’ultimo stabile di Microsoft, cioè Visual Studio 2008. Tale IDE è uno strumento eccellente per i programmatori, ma presenta alcune carenze per i designer e quanti in generale si occupano di grafica. Per colmare tale lacuna Microsoft ha lanciato sul mercato quattro ambienti di sviluppo aggiuntivi (Expression Web, Expression Blend, Expression Design ed Expression Media), che supportano WPF e Silverlight, permettendo ai designer di sviluppare la parte grafica, andandola poi ad integrare con la logica sviluppata dai programmatori attraverso Visual Studio 2008. E’ possibile utilizzare contemporaneamente sia il Visual Studio sia gli Expression sfruttando al massimo le capacità dei vari ambienti di sviluppo. I dettagli di Visual Studio e dei moduli .NET sono presentati in [1] e [2].

Questi componenti tecnologici ampliano enormemente le potenzialità di realizzazione di applicativi Web, ma nel contempo rendono più complessa la loro struttura. Per realizzare applicazioni manutenibili e facilmente evolvibili quindi non è più possibile la struttura monolivello di pagine che accedono direttamente alla base dati, ma, sfruttando anche le suddivisioni già presenti entro l’architettura .NET, occorre definire un’architettura per le applicazioni web, che verrà presentata nel paragrafo successivo. Entro pochi mesi uscirà la versione successiva, Visual Studio 2010, affiancata al framework .NET 4.0.

Ingegnerizzare il web: le applicazioni stratificate

Da tempo le architetture software stanno evolvendosi verso strutture stratificate, soprattutto nei linguaggi basati su oggetti, allo scopo di favorire manutenibilità e adattabilità del software. D’altronde la stratificazione ha una sua origine logica: infatti, entro una qualsiasi applicazione interattiva, è sempre possibile individuare tre elementi distinti: la logica di presentazione, che forma l’interfaccia utente, la logica funzionale, che comprende gli algoritmi di calcolo veri e propri (chiamata anche spesso logica business) e i dati, che devono durare oltre l’esecuzione del programma e che per questo motivo vengono memorizzati in supporti esterni al programma stesso, tipicamente file o database relazionali.

Il pattern architetturale Model-View-Controller (MVC), definito nel 1979 dal professor T. Reenskaug (si vedano anche [3] e [4]), è forse il modello teorico più noto nell’ambito del design di applicazioni stratificate e da esso sono derivati molti altri pattern. MVC definisce fondamentalmente tre componenti principali che specificano quali sono i ruoli delle diverse parti che andranno a costituire l’applicazione stessa.

  • Model: rappresenta l’insieme dei componenti responsabili della gestione ed elaborazione dei dati internamente al programma e al suo interno stanno anche le componenti per la lettura e scrittura dei dati da e verso il sistema di memorizzazione permanente. Al suo interno viene costruita la logica funzionale.
  • View: è l’insieme dei componenti responsabili della visualizzazione dei dati per l’utente e della raccolta degli eventi legati alle azioni dell’utente, che trasmette al terzo elemento, il Controller.
  • Controller: reagisce agli eventi trasmessi dalla View e gestisce la logica operativa dell’applicazione, si occupa di verificare la correttezza del flusso dati e permette lo scambio di informazioni tra il View ed il Model.

clip_image011

Figura 3: rappresentazione del modello MVC teorico

Il modello MVC ha dato origine più o meno direttamente a molti framework e metodologie, come per esempio Struts e gli EJB nel mondo Java, e la sua impronta è chiaramente visibile anche nel mondo .NET a partire dalla versione 2.0 del framework. Inoltre Microsoft ha da poco una estensione di .NET chiamata ASP.NET MVC che implementa direttamente il modello MVC. In ogni caso, applicando le linee guida di MVC si può definire una metodologia di sviluppo estremamente utile che si sposa bene con la struttura di .NET 3.5 (si veda [4] per approfondimenti).

I tre componenti possono essere mappati sulle strutture di .NET come segue:

la View è il componente XHTML (nel 2.0) o XAML, eventualmente corredato di elementi AJAX.NET e/o Silverlight;

il Controller è il file contenente il code-behind della form o web form, ove stanno i metodi reattori che reagiscono agli eventi trasmessi loro dai corrispondenti elementi visuali della view;

il Model è la class library contenete le classi con la vera logica funzionale, i cui metodi pubblici vengono invocati dai metodi reattori presenti nel Controller. Questa implementazione del Model non segue completamente il modello teorico, ma sfrutta la suddivisione in progetti delle applicazioni .NET ed il pattern Wrapper.

Questo approccio presenta il notevole vantaggio di separare completamente tutta la parte di sviluppo dell’interfaccia utente da quella della logica funzionale, permettendo, da un lato, la possibilità di creare librerie di elementi di logica funzionale facilmente adattabili (o meglio inseribili) in nuovi siti e/o applicazioni e dall’altro di separare tra loro il lavoro dei programmatori e quello dei designer. La logica funzionale può inoltre essere comune tra applicazioni desktop e web. Ma, soprattutto, entro un sito web non occorre inserire alcun codice sorgente (tranne quello del controller, ove però al più dovrebbero stare elementi di verifica dell’input e che per il resto dovrebbe limitarsi a richiamare internamente i metodi delle classi di libreria), ma solo delle .dll precompilate. Questo facilita la realizzazione di componenti, installabili anche presso siti di terze parti o vendibili sul mercato. Lo svantaggio è dato dalla maggiore complessità architetturale, che richiede sicuramente una progettazione e può aumentare i tempi di sviluppo.

In quanto segue vedremo l’utilizzo di questa metodologia per lo sviluppo completo di un’applicazione web sfruttando i nuovi elementi di ASP.NET 3.5.

Costruire un’applicazione web stratificata

L’applicativo di esempio è un prototipo con elementi comuni sia alle applicazioni web dinamiche (come, per esempio, un catalogo di prodotti), sia alle applicazioni gestionali con interfaccia web. Esso infatti comprende un database contenente un’anagrafica, una maschera di interrogazione per chiavi (filtro) con una componente di presentazione dei risultati in forma di tabella.

Seguendo la suddivisione sopra descritta l’architettura dell’applicativo diventa quella descritta in figura 4.

clip_image013

Figura 4: struttura a blocchi della tipologia di progetto seguita nell’esempio

Per potere usufruire anche dei servizi ASP.NET AJAX occorre installare alcune estensioni alla dotazione standard di Visual Studio 2008.

Prima di tutto occorre installare il file ASPAJAXExtSetup.msi, scaricabile dai siti Microsoft ma presente anche nell’esempio nella cartella ComponentiAggiuntivi. Poi si deve installare l’estensione di Visual Studio contenuta nel file AjaxControlExtender.vsi, per il quale è sufficiente un doppio click a Visual Studio spento. Infine, per potere disporre dei componenti aggiuntivi usati, occorre installare l’AjaxControlToolkit, libreria gratuita scaricabile da [5].

L’AjaxControlToolkit è necessario per il run del progetto e per questo si trova compreso entro il progetto stesso, ma per potere usufruire anche dei suoi componenti in compilazione occorre seguire i seguenti passi:

  1. Espandere il file AjaxControlToolkit.zip entro una cartella di sistema (es. C:\programmi);
  2. Creare nel toolbox di Visual Studio un nuovo elemento, posizionandosi con il cursore all’interno dello stesso toolbox e selezionando Add Tab dal menu del tasto destro;
  3. Nominare l’elemento Ajax Control Toolkit;
  4. Poszionarsi entro questo nuovo tab e selezionare dal tasto destro del mouse la voce Choose Items
  5. Dal menu di scelta, cliccare il pulsante browse e selezionare il file C:\programmi\AjaxControlToolkit\SampleWebSite\Bin\AjaxControlToolkit.dll (come mostrato in Figura 5)
  6. Accettando gli elementi preselezionati mostrati nel menu .Net Framework Component, cliccare su OK (come mostrato in Figura 6).

clip_image015

Figura 5: ricerca degli elementi di estensione al Toolbox

clip_image017

Figura 6: i componenti di Ajax Control Toolkit pronti per l’inclusione nel Toolbox di VS2008

Questo renderà disponibili 28 nuovi componenti Ajax nel Toolbox di Visual Studio 2008. Esempi molto utili per l’applicazione di tali componenti sono reperibili a Devil.

E ora vediamo nei dettagli la realizzazione passo-passo dell’applicativo con Visual Studio 2008.

La soluzione prende il nome di EsempioMVCAsp ed al suo interno troviamo un progetto libreria, CL_Adapter, contenente la logica di business dell’applicativo (quindi la parte di codice del Model) ed un progetto applicazione Web, WebEsempioMVC, con la logica di presentazione (quindi View e Controller).

La base dati di esempio comprende una tabella Clienti, con vari dettagli, di cui vengono usati i record in parte o tutti secondo il tipo di visualizzazione. Il database è un SQL Server, (DatabaseEsempio.mdf), e si trova nella cartella AppData, secondo lo standard degli attached file. Per usare la stringa di connessione già presente nella classe Adapter potrebbe essere necessario adattare la stringa stessa se l’istanza locale di SQL Server non è un express.

clip_image019

Figura 7: la tabella di esempio nell’applicazione

All’interno della libreria sono due classi principali, Adapter.cs e AdapterLinq.cs, che costituiscono la logica di accesso ai dati e hanno interfacce esterne uguali. La classe Adapter è costruita con OleDB e query SQL, mentre la classe AdapterLinq si basa sul mapping Linq to SQL. Analizziamo alcune parti della Classe Adapter. Tra gli attributi sono la stringa di connessione al db e stringhe contenenti le query in formato SQL.

Due metodi per l’apertura e la chiusura della connessione al database completano la parte generale della classe. Ora potremmo procedere direttamente con le query, ma possiamo racchiudere il codice fondamentale in due metodi, uno per eseguire query con parametri ed uno per query senza alcun parametro:

  1: private DataTable ExecuteSelect(string p_sqlSelect)
  2: {
  3:     // creazione dell'oggetto comando OleDB
  4:     OleDbCommand cmd = new OleDbCommand();
  5: 
  6:     // associazione della query al comando
  7:     cmd.CommandText = p_sqlSelect;
  8: 
  9:     // assegnazione della connessione al comando
 10:     cmd.Connection = dbConn;
 11: 
 12:     // verifica che la connessione sia aperta
 13:     if (dbConn.State == ConnectionState.Closed)
 14:     {
 15:         // e lancia una eccezione in caso contrario
 16:         Exception err = new Exception("Connessione al DB chiusa!");
 17:         throw err;
 18:     }
 19: 
 20:     // crea un DataReader associato al comando
 21:     OleDbDataReader reader = cmd.ExecuteReader();
 22: 
 23:     // attraverso il metodo load 
 24:     // i contenuti del datareader 
 25:     // vengono caricati in una datatable
 26:     DataTable dt = new DataTable();
 27:     dt.Load(reader);
 28: 
 29:     // ritorna la DataTable cosi' ottenuta
 30:     return dt;
 31: 
 32: } // end method ExecuteSelect
 33: 
 34: private DataTable ExecuteSelectWithParam(string p_sqlSelect, string p_key, string p_param)
 35: {
 36:     // creazione dell'oggetto comando DB
 37:     OleDbCommand cmd = new OleDbCommand();
 38: 
 39:     // assegnazione della query al comando
 40:     cmd.CommandText = p_sqlSelect;
 41: 
 42:     // assegnazione della connessione al comando
 43:     cmd.Connection = dbConn;
 44: 
 45:     // creazione dell'oggetto DbParameter associato alla chiave e al valore
 46:     OleDbParameter par1 = new OleDbParameter(p_key, p_param);
 47: 
 48:     // aggiunta del parametro al DbCommand
 49:     cmd.Parameters.Add(par1);
 50: 
 51:     // verifica che la connessione sia aperta
 52:     if (dbConn.State == ConnectionState.Closed)
 53:     {
 54:         // e lancia una eccezione in caso contrario
 55:         Exception err = new Exception("Connessione al DB chiusa!");
 56:         throw err;
 57:     }
 58: 
 59:     // crea un DataReader associato al comando
 60:     OleDbDataReader reader = cmd.ExecuteReader();
 61: 
 62:     // attraverso il metodo load 
 63:     // i contenuti del datareader 
 64:     // vengono caricati in una datatable
 65:     DataTable dt = new DataTable();
 66:     dt.Load(reader);
 67: 
 68:     // ritorna la DataTable cosi' ottenuta
 69:     return dt;
 70: } // end method ExecuteSelectWithParam

Questi metodi vengono poi usati per l’esecuzione di query con o senza parametri, come nell’esempio di codice sottostante:

  1: //Carica solo ID, Nome, Cognome dal record
  2: public DataTable GetData()
  3: {
  4:     return this.ExecuteSelect(sql_GetDataDetail);
  5: }

Per semplicità si è stabilito che i metodi di ricerca restituiscano una DataTable, per facilitare poi la distribuzione dei dati in oggetti come GridView e simili. Sarebbe stato possibile anche fare ritornare ai metodi liste di oggetti entità o altri tipi di strutture dati.

Ora possiamo creare parallelamente alla classe Adapter una classe AdapterLinq che avrà la stessa interfaccia esterna, e quindi potrà essere “intercambiabile” con la precedente, ma che sfrutterà internamente Linq to SQL per l’accesso ai dati.

E’ necessario quindi creare un elemento di mapping DataClassLinq.dbml e inserire in esso la tabella Clienti, attraverso il drag-and-drop della tabella dal database, come mostrato in figura 8:

clip_image021

Figura 8: costruzione del mapping con il file .dbml

Il collegamento alla base di dati attraverso LINQ si realizza istanziando internamente all’AdapterLinq la classe ottenuta dall’elemento di mapping come un attributo

DataClassLinqDataContext db = new DataClassLinqDataContext();

Ora possiamo come prima costruire i nostri metodi Linq che devono restituire sempre una DataTable, utilizzando gli appositi costrutti select di questa estensione del linguaggio C#. Occorre un metodo per convertire il risultato di Linq in una data table

  1: public DataTable ObtainDataTableFromIEnumerable(System.Collections.IEnumerable p_ien)
  2: {
  3:     // creazione di una DataTable vuota
  4:     DataTable dt = new DataTable();
  5: 
  6:     // per tutti gli elementi presenti nell'IEnumerable passato come parametro
  7:     foreach (object obj in p_ien)
  8:     {
  9:         // determinazione di classe e proprieta' dell'oggetto
 10:         Type t = obj.GetType();
 11:         PropertyInfo[] pis = t.GetProperties();
 12: 
 13:         // riempimento dei nomi delle colonne
 14:         if (dt.Columns.Count == 0)
 15:         {
 16:             foreach (PropertyInfo pi in pis)
 17:             {
 18:                 dt.Columns.Add(pi.Name, pi.PropertyType);
 19:             } // end foreach
 20:         } // end if
 21: 
 22:         // creazione di una nuova riga
 23:         DataRow dr = dt.NewRow();
 24: 
 25:         // per tutti gli oggetti
 26:         foreach (PropertyInfo pi in pis)
 27:         {
 28:             // inserimento del valore degli oggetti stessi
 29:             object value = pi.GetValue(obj, null);
 30:             dr[pi.Name] = value;
 31:         } // end foreach 
 32: 
 33:         // aggiunta della nuova riga alla lista delle righe in dt
 34:         dt.Rows.Add(dr);
 35:     } // end foreach object in p_ien
 36: 
 37:     // ritorno della data table
 38:     return dt;
 39: } // end method ObtainDataTableFromIEnumerable

Che poi viene utilizzato entro i metodi con la interrogazione Linq

  1: public DataTable GetData()
  2: {
  3:     // estrazione di dati con LINQ
  4:     var results = from c in db.Clientis
  5:                   select new { c.Id, c.Cognome, c.Nome };
  6: 
  7:     // ritorna l'elemento convertito in DataTable
  8:     return ObtainDataTableFromIEnumerable(results);
  9: } // end method GetData

Abbiamo quindi a disposizione due Adapter equivalenti che accedono alla base dati ed estrapolano i dati desiderati, sviluppati il primo con il consolidato OleDb e le query dirette e il secondo con Linq. Il progetto con interfaccia utente che viene creato è Web ma ovviamente la libreria creata potrebbe essere sfruttata anche per applicativi WindowsForm.

Per usare la libreria nel progetto Web basta aggiungere una reference al progetto come mostrato in figura:

clip_image023

Figura 9: reference al progetto della libreria associata al progetto Web

L’obbiettivo è costruire un semplice gestore di dati in cui visioneremo attraverso una GridView i dati dei clienti, e facendo click su una riga potremmo vedere con un effetto Ajax i dettagli dei Clienti.

Occorre quindi aggiungere al progetto una GridView collegata ad un ObjectDataSource, a sua volta connesso alla libreria; in figura sono mostrati i passi per configurarli:

clip_image025

clip_image027

Figura 10: i passaggi per l’agganciamento dell’ObjectDataSource alla libreria

Sia per l’AdapterLinq sia per l’altro possiamo selezionare il metodo desiderato per il caricamento dei dati

clip_image029

Figura 11: scelta del metodo di select

A questo punto non rimane che collegare la GridView all’ObjectData Source

clip_image031

Figura 12: collegare la GridView all’ObjectDataSource

Eseguendo il progetto si vede il caricamento dei dati con un risultato identico per entrambi i componenti

clip_image033

Figura 13: l’output del programma

Nell’esempio viene utilizzato, tra i componenti aggiunti di AJAX Control Toolkit il ModalPopupExtender.

clip_image035

Figura 14: inserimento del pulsante di selezione riga entro la GridView

Dobbiamo aggiungere un pulsante Edit con CommandName “Detail” , aggiungiamo al progetto lo scriptmanager ed inseriamovi il riferimento alla dll di Ajax Control Toolkit:

  1: <%@ Register Assembly="AjaxControlToolkit" Namespace="AjaxControlToolkit" TagPrefix="AjaxControl" %>

Ora si può inserire una DetailView all’interno di un panel che sarà mostrerato come pop-up al click dell’utente sull’immagine corrispondente a quel determinato cliente:

  1: <!--DetailView Nascosta-->
  2: <asp:Button ID="btnHiddenUpdate" runat="Server" Style="display: none" />
  3: <ajaxcontrol:modalpopupextender id="mpeUpdate" runat="server" targetcontrolid="btnHiddenUpdate"
  4:     popupcontrolid="pnlUpdate" cancelcontrolid="btnCancelUpdate" backgroundcssclass="modalBackground"
  5:     popupdraghandlecontrolid="UpdateCaption" drag="true">
  6: 
  7: </ajaxcontrol:modalpopupextender>
  8: <asp:Panel ID="pnlUpdate" runat="server" Style="display: none; background-image: url('../Image/web.update.gif')"
  9:     Height="400px" Width="400px" HorizontalAlign="Center">
 10:     <br />
 11:     <br />
 12:     <br />
 13:     <br />
 14:     <asp:DetailsView ID="ClientDetail" runat="server" AutoGenerateRows="False" CellPadding="4"
 15:         DataSourceID="objData" DefaultMode="Edit" EnablePagingCallbacks="True" ForeColor="#333333"
 16:         GridLines="None" Height="270px" Width="350px">
 17:         <FooterStyle BackColor="#507CD1" Font-Bold="True" ForeColor="White" />
 18:         <CommandRowStyle BackColor="#D1DDF1" Font-Bold="True" />
 19:         <RowStyle BackColor="#EFF3FB" />
 20:         <FieldHeaderStyle BackColor="#DEE8F5" Font-Bold="True" />
 21:         <PagerStyle BackColor="#2461BF" ForeColor="White" HorizontalAlign="Center" />
 22:         <Fields>
 23:             <asp:BoundField DataField="id" HeaderText="ID: " ReadOnly="True">
 24:                 <FooterStyle HorizontalAlign="Left" />
 25:                 <HeaderStyle HorizontalAlign="Left" />
 26:                 <ItemStyle HorizontalAlign="Center" />
 27:             </asp:BoundField>
 28:             <asp:BoundField DataField="Nome" HeaderText="Nome :">
 29:                 <FooterStyle HorizontalAlign="Left" />
 30:                 <HeaderStyle HorizontalAlign="Left" />
 31:             </asp:BoundField>
 32:             <asp:BoundField DataField="Cognome" HeaderText="Cognome :">
 33:                 <HeaderStyle HorizontalAlign="Left" />
 34:             </asp:BoundField>
 35:             <asp:BoundField DataField="Indirizzo" HeaderText="Indirizzo :">
 36:                 <HeaderStyle HorizontalAlign="Left" />
 37:             </asp:BoundField>
 38:             <asp:BoundField DataField="Citta" HeaderText="Città :">
 39:                 <HeaderStyle HorizontalAlign="Left" />
 40:             </asp:BoundField>
 41:             <asp:BoundField DataField="cap" HeaderText="Cap :">
 42:                 <HeaderStyle HorizontalAlign="Left" />
 43:             </asp:BoundField>
 44:             <asp:BoundField DataField="Tipologia" HeaderText="Tipologia">
 45:                 <HeaderStyle HorizontalAlign="Left" />
 46:             </asp:BoundField>
 47:         </Fields>
 48:         <HeaderStyle BackColor="#507CD1" Font-Bold="True" ForeColor="White" />
 49:         <EditRowStyle BackColor="#2461BF" />
 50:         <AlternatingRowStyle BackColor="White" />
 51:     </asp:DetailsView>
 52:     <asp:ImageButton ID="btnCancelUpdate" runat="server" CausesValidation="false" Height="46px"
 53:         ImageUrl="~/Image/p.cancel.jpg" Style="text-align: center" Text="Cancel" Width="71px" />
 54: </asp:Panel>

Abbiamo quindi creato una detailView sempre associata all’ObjectDataSource che sarà visualizzata al clik dell’utente. Ora dobbiamo intercettare correttamente il click e far comparire il pop-up:

  1: protected void grvCustomer_RowCommand(object sender, GridViewCommandEventArgs e)
  2: { //Recupero il Command Name per visualizzare i dettagli del cliente
  3:     if (e.CommandName == "DETAIL")
  4:     {
  5:         int _rowIdx = Convert.ToInt32(e.CommandArgument);
  6:         ClientDetail.PageIndex = _rowIdx;
  7:         mpeUpdate.Show();
  8:     }
  9: }

Il risultato sarà quindi il seguente:

clip_image037

Figura 15: finestra AJAX di dettaglio del singolo record

Possiamo inoltre sfruttare un altro componente del framework 3.5, l’Entity Framework, che ci permette di separare la logica applicativa dalla business logic in pochi passaggi. Questo nuovo ORM ci permette di estrarre facilmente i dati da un db e mapparli su strutture dati in memoria come fossero oggetti. Nella prossima release 4.0 del framework questo strumento probabilmente diventerà un punto di riferimento fondamentale per ogni sviluppatore .NET. Vediamo ora come usarlo nel nostro progetto:

1. Requisito fondamentale è quello di avere installato la sp1 di Visual Studio 2008

2. Creare un nuovo progetto di libreria e aggiungere il componente Ado Entity Data Model ed associarlo alla nostra base dati

clip_image039

3. Creare una classe per popolare la data grid view

  1: public class AdapterEF
  2: {
  3:     ESEMPIOEntities dbEF = new ESEMPIOEntities();
  4: 
  5:     //Carico i dati da EF
  6:     public List<Clienti> GetFullData()
  7:     {
  8:         var query_selectAll = from b in dbEF.Clienti select b;
  9:         return query_selectAll.ToList();
 10:     }
 11: }

Con questi passi siamo riusciti a sfruttare le potenzialità di questo strumento separando la logica dei dati dalla restante parte di business. Esistono tool che cercano di utilizzare pienamente il paradigma MVC come ASP.NET MVC ed esistono altri ORM diffusi, come NHIBERNATE. L’esempio presentato mostra un’introduzione “didattica” verso un’approccio stratificato nello sviluppo di applicazioni.

Nel modo indicato si è ottenuta una netta separazione tra l’interfaccia utente e la logica interna. La stessa interfaccia utente funziona con logiche interne diverse e la stessa logica interna può essere riutilizzata con diverse interfacce utente.

Conclusioni

Dalla struttura del progetto risulta ancora più evidente il disaccoppiamento tra la parte di interfaccia e la parte di logica business. Questa sarebbe potuta essere realizzata con OleDB e le relative istruzioni SQL esplicite, con il modello visuale del DataSet o in altri modi ancora. A parità di interfaccia esterna e di elementi di trasferimento, gli strati di interfaccia utente non sono in relazione con il tipo di implementazione.

La parte di interfaccia utente avrebbe potuto essere facilmente realizzata anche in XBAP puro o in XHTML come nel .NET 2.0. AJAX e, entro certi limiti, Silverlight attualmente garantiscono la migliore portabilità per una RIA. In particolare, il progetto open source Moonlight di Novell sta procedendo rapidamente allo sviluppo di un ambiente multipiattaforma compatibile con Silverlight, garantendo il funzionamento di questa tecnologia anche su client aventi sistemi operativi Unix o MacOS.

Modifiche da apportare per il funzionamento dell’esempio allegato:

Per fare funzionare correttamente l’esempio è necessario collegare ObjectDataSource alla classe di libreria adeguata e verificare la connessione al database:

clip_image005 Se si usa la classe Adapter custom:

Selezionare dal ObjectDataSource CL_Adapter_Adapter.

clip_image041

Nella Classe libreria CL_Adapter\Adapter.cs impostare correttamente la stringa di connessione al database di esempio contenuto nella cartella App_Data

clip_image005[1] Se si usa la classe AdapterLinq:

Selezionare dal ObjectDataSource CL_Adapter\AdapterLinq.

Nella classe libreria eliminare nel file DataClassLinq.dbml la tabella clienti, e importarla nuovamente attraverso il drag-and-drop dal database di esempio presente nella cartella App_Data

Bibliografia

[ 1] Tutorial e articoli su .NET 3.5: http://netfx35.winfxitalia.com/

[ 2] Tutorial su ASP.NET: http://aspdotnet3.5.aspitalia.com/

[ 3] Pagina di Wikipedia su MVC: http://en.wikipedia.org/wiki/Model-view-controller

[ 4] G.Destri, O.Figus, A.Picca “AreaMVC: Linee guida per l’applicazione pratica di MVC in .NET e Java”: http://www.areaprofessional.net/documenti/AreaMVC.pdf

[ 5] Codeplex AJAX Control Toolkit: http://www.codeplex.com/AtlasControlToolkit.

[ 6] Esempi d’uso di AJAX Control Toolkit: http://www.asp.net/ajax/ajaxcontroltoolkit/samples/.

 

I file dell’articolo sono scaricabili da : http://www.ingegneridelweb.com/public/sorgenti/esempioMvc.zip

 

MARCO MALTRAVERSI  

E' laureato magistrale in Ingegneria Informatica presso l'Università degli studi di Parma;specializzazione: Tecnologia dei sistemi informativi.

Dal 2002 lavora nello sviluppo web e nella consulenza in campo informatico, è stato docente di Informatica in Istituti di Istruzione Superiore ed è abilitato alla professione dell'Ingegnere.

E' stato collaboratore come progettista e sviluppatore di applicazioni Web/Form presso Area Solutions Providers, attualmente lavora presso Frati S.p.a come esperto EDP e sviluppatore in AS400/DB2 e c#. Recentemente ha conseguito la qualifica di SEO specialist e collabora con www.ingegneridelweb.com. Autore di un libro tecnico su Windows 7, edizioni FAG, 
e del libro “SEO e SEM Guida Avanzata al Web Marketing” www.libro-seo.it. Consulente SEO per agenzie Italiane e Estere di Web Marketing e si occupa di formazione professionale sul territorio Italiano sia in corsi di programmazione sia in corsi seo. 

E' contattabile attraverso i suoi blog:

http://blogs.ugidotnet.org/maltra/
http://blogs.dotnethell.it/maltra/

 

Only published comments... Dec 05 2009, 09:07 PM by DotNetSide Staff

Comments

 

.Net Tutto e Oltre di Marco Maltraversi said:

Il Web di nuova generazione: gestire efficacemente le nuove tecnologie .NET

December 8, 2009 5:15 AM
Powered by Community Server (Commercial Edition), by Telligent Systems