Gli ASP.NET Dynamic Data, introdotti con il Service Pack 1 di Visual Studio 2008, consentono di realizzare con estrema facilità complete applicazioni Web per la gestione di basi di dati, creando automaticamente tutte le pagine che servono per visualizzare e modificare le informazioni.
Su AspNET.HTML.it abbiamo già introdotto questo framework con due articoli:
Una caratteristica molto interessante degli ASP.NET Dynamic Data è che nella visualizzazione di ogni tabella è inclusa in automatico una serie di campi per filtrare i dati.
Le ricerche si limitano però ai soli valori delle chiavi esterne e delle colonne booleane. Questa funzionalità, dunque, sebbene interessante, è un po' limitata: in ogni sito che si rispetti, infatti, deve essere presente anche una funzione di ricerca con testo libero.
Sul Wiki dedicato al framework si legge che la prossima versione includerà strumenti più sofisticati per la creazione di maschere di ricerca. Non è tuttavia necessario attendere questo rilascio per potenziare le funzionalità di ricerca di un sito Dynamic Data: su CodePlex è infatti disponibile un progetto chiamato Dynamic Data Filtering, che estende la piattaforma dei Dynamic Data permettendo di effettuare ricerche libere su ogni tipo di colonna.
Come vedremo, con questo sistema possiamo costruire maschere di ricerca in maniera completamente dichiarativa, ovvero solo inserendo nella pagina una serie di controlli, senza scrivere una riga di codice.
Installazione
Dal sito del progetto è possibile scaricare il pacchetto Dynamic Data Filtering in diverse modalità, ma si consiglia di utilizzare quello denominato Dynamic Data Filtering Installer (DynamicDataFiltering.msi
), che copierà nel sistema tutti gli assembly necessari al suo utilizzo e aggiungerà una serie di oggetti nella sezione Data
della Casella degli strumenti di Visual Studio, abilitando quindi il supporto in modalità di progettazione grafica.
Se non indicato diversamente, il setup installa le librerie nella cartella C:ProgrammiDynamic Data Filtering
, insieme ad un'applicazione di esempio disponibile sia per C# sia per Visual Basic .NET.
Utilizzare Dynamic Data Filtering
L'utilizzo dei filtri è molto semplice: colleghiamoci ad un'istanza di SQL Server a cui abbiamo accesso e creiamo un database di prova, di nome AddressBook
, utilizzando lo script Create.sql
allegato a questo articolo.
Avviamo poi Visual Studio e definiamo una nuova Dynamic Data Web Application
, chiamata anch'essa AddressBook
, come indicato nell'articolo precedente.
Il database importato nel LINQ-to-SQL Designer apparirà in questo modo:
Proviamo ad eseguire il sito e visualizziamo l'elenco degli utenti: noteremo che la pagina contiene una DropDownList
per filtrarli in base alla città, ovvero l'unica chiave esterna definita nella tabella.
Personalizzare il filtro
Ora possiamo modificare la pagina perché consenta di effettuare anche ricerche per nome, quindi creiamo un template personalizzato per la visualizzazione della lista dei contatti della nostra rubrica. Aggiungiamo, all'interno della cartella DynamicDataCustomPages
, una directory con lo stesso nome della tabella del database per cui vogliamo ridefinire le pagine, ovvero Users
.
Fatto questo, visualizziamo il contenuto della cartella DynamicDataPageTemplates
, al cui interno troviamo i template utilizzati dal motore di scaffolding per creare le pagine temporanee in cui saranno mostrati i dati. Nella nuova cartella Users dobbiamo copiare i file corrispondenti alle funzioni da personalizzare: quando il sistema dovrà gestire la tabella in questione, andrà prima a verificare l'esistenza di un template adatto in DynamicDataCustomPagesUsers
: se lo trova, lo utilizzerà per generare la pagina, altrimenti si baserà sul template base contenuto in PageTemplates
.
Per il nostro scopo, quindi, dobbiamo copiare la pagina List.aspx
contenuta in DynamicDataPageTemplates
ed inserirla in DynamicDataCustomPagesUsers
. Ora dobbiamo rinominare il namespace in cui è definita, perché altrimenti il suo nome andrebbe in conflitto con quello già esistente.
Apriamo il file List.aspx
e sostituiamo Inherits="AddressBook.List"
con Inherits="AddressBook.Users.List"
, quindi ripetiamo l'operazione per il file List.aspx.cs
, cambiando la dichiarazione namespace AddressBook
in namespace AddressBook.Users
.
Possiamo finalmente creare la maschera di ricerca vera e propria: inserendola nel file DynamicDataCustomPagesUsersList.aspx
, essa sarà utilizzata solo per l'elenco dei contatti, mentre le altre tabelle continueranno a basarsi sul template standard. Apriamo dunque questo file ed eliminiamo l'oggetto FilterRepeater
, che è responsabile della visualizzazione automatica dei campi di ricerca per le colonne booleane e le chiavi esterne, come abbiamo detto all'inizio:
<asp:FilterRepeater ID="FilterRepeater" runat="server"> <ItemTemplate> <asp:Label runat="server" Text='<%# Eval("DisplayName") %>' AssociatedControlID="DynamicFilter$DropDownList1" /> <asp:DynamicFilter runat="server" ID="DynamicFilter" OnSelectedIndexChanged="OnFilterSelectedIndexChanged" /> </ItemTemplate> <FooterTemplate><br /><br /></FooterTemplate> </asp:FilterRepeater>
Al suo posto, dobbiamo inserire un oggetto dei Dynamic Data Filtering
. Visualizziamo la pagina in modalità Design e trasciniamo in essa il controllo DynamicFilterForm
:
Una volta posizionato il controllo, un messaggio ci chiede se vogliamo inserire nel progetto i template di ricerca predefiniti. Clicchiamo pure su Sì
, in questo modo, nella cartella DynamicData
sarà aggiunta la directory FilterTemplates
.
Così come FieldTemplates
contiene i controlli ASCX
utilizzati per mostrare i dati, in FilterTemplates
trovano posto gli oggetti ASCX
per immettere i criteri di ricerca: Text.ascx
per il testo, Boolean.ascx
per i campi booleani, ForeignKey.ascx
per le chiavi esterne, Integer_Range.ascx
per indicare un intervallo numerico, etc.
Ora dobbiamo associare questo nuovo oggetto al Data Source della pagina. Clicchiamo sullo smart tag del controllo DynamicFilterForm
(ovvero il piccolo riquadro con il segno di >
visualizzato in alto a destra nell'oggetto), quindi selezioniamo GridDataSource
nella lista Choose Data Source
e, infine, eseguiamo il comando Upgrade Data Source
:
Seguendo questi passaggi, il DynamicFilterForm
viene associato alla griglia sottostante e l'oggetto per accedere alla fonte dati passa automaticamente da LinqDataSource
a DynamicLinqDataSource
, ovvero un particolare Data Source, incluso nei Dynamic Data Filtering, in grado di mostrare i dati utilizzando i filtri di ricerca impostati nella maschera.
Ora visualizziamo il markup della pagina List.aspx
ed evidenziamo il tag asp:DynamicFilterForm
. Al suo interno dobbiamo inserire i campi di ricerca che vogliamo definire. Modifichiamo quindi il controllo in modo che risulti come indicato di seguito:
<asp:DynamicFilterForm ID="DynamicFilterForm1" runat="server" DataSourceID="GridDataSource">
<FilterTemplate>
<div>Search</div>
<div>
Nome: <asp:DynamicFilterControl DataField="Name" FilterMode="Contains" ID="FiltroNome" runat="server" />
Città: <asp:DynamicFilterControl DataField="City" ID="FilroCitta" runat="server" />
<asp:LinkButton ID="SearchButton" runat="server" CommandName="Search" Text="Search"></asp:LinkButton>
<asp:LinkButton ID="ClearButton" runat="server" CommandName="Clear" Text="Clear"></asp:LinkButton>
</div>
</FilterTemplate>
</asp:DynamicFilterForm>
In questo caso abbiamo definito due campi di ricerca, uno per il nome e uno per la città. Ognuno di essi corrisponde ad un oggetto di tipo DynamicFilterControl
, in cui l'attributo DataField
è uguale al nome del campo a cui si riferisce (ovvero, rispettivamente, Name
e City
). La proprietà FilterMode
, invece, è facoltativa e indica il tipo di ricerca che si vuole effettuare. Nel nostro esempio abbiamo usato Contains
per il campo Name
, indicando quindi di voler trovare tutti i contatti il cui nome contiene il testo indicato (ovvero, in termini di SQL, fare una ricerca di tipo LIKE %espressione%
).
Abbiamo finito: come detto all'inizio, per implementare la funzionalità di ricerca non è stato necessario scrivere neanche una riga di codice. Tutto questo funziona perché, in base al tipo di dati della colonna e all'eventuale parametro di FilterMode
, il sistema è in grado di determinare automaticamente il controllo con cui mostrare il campo di ricerca: la colonna Name
è di tipo NVARCHAR
e il filtro è impostato su Contains
, quindi sarà utilizzato l'oggetto contenuto nel file FilterTemplatesText_Contains.ascx
; analogamente, poiché City
è una chiave esterna, il relativo filtro di ricerca si baserà sul file FilterTemplatesForeignKey.ascx
.
Verifichiamo il risultato
A questo punto, possiamo avviare il sito premendo F5
e visualizzare la tabella Users
:
Osserviamo la nuova maschera di ricerca, in cui abbiamo una casella di testo per il nome e una DropDownList
da cui scegliere la città che vogliamo trovare. Premendo il link Search
, verrà avviata la ricerca e il contenuto della griglia sottostante sarà automaticamente filtrato in base a tutti i criteri impostati. Con il comando Clear
, infine, abbiamo la possibilità di annullare la ricerca, mostrando di nuovi tutti i contatti.
Personalizzare la maschera di ricerca
La maschera di ricerca, all'interno del DynamicFilterForm, è definita per mezzo di un oggetto di tipo FilterTemplate
, quindi il suo aspetto può essere personalizzato per adattarlo al resto del sito. Analizziamo ad esempio la seguente dichiarazione:
<asp:DynamicFilterForm ID="DynamicFilterForm1" runat="server" DataSourceID="GridDataSource"> <FilterTemplate> <div style="border: 2px solid LightGray; width: 100%"> <h4>Ricerca</h4> <table style="width: 100%"> <tr> <td style="width:30px">Nome:</td> <td><asp:DynamicFilterControl ID="DynamicFilterControl1" runat="server" DataField="Name" FilterMode="Contains" /></td> <td style="width:30px">Città:</td> <td><asp:DynamicFilterControl ID="DynamicFilterControl2" runat="server" DataField="City" /></td> <td style="text-align:right"> <asp:Button ID="SearchButton" runat="server" Text="Search" CommandName="Search" /> <asp:Button ID="ClearButton" runat="server" Text="Clear" CommandName="Clear" /> </td> </tr> </table> </div> </FilterTemplate> </asp:DynamicFilterForm>
La maschera è stata racchiusa in un <div>
, i campi sono stati inseriti in una tabella e i link per la ricerca sono stati sostituiti da due pulsanti:
L'applicazione di esempio è disponibile per il download. Per la sua corretta esecuzione, è necessario modificare il file web.config
aggiornando la stringa di connessione in modo che punti al database nel proprio sistema.
Conclusioni
In questo articolo abbiamo mostrato un semplice esempio d'uso del pacchetto Dynamic Data Filtering. Il sistema offre molto di più, ad esempio la possibilità di creare nuovi controlli per realizzare funzionalità di ricerca non previste nei template standard. Per approfondire l'argomento, si consiglia di visitare il sito del progetto su CodePlex, in particolare le sezioni Discussions e Issue Tracker, e il blog dell'autore, in cui si possono trovare diversi esempi di utilizzo più avanzato della libreria.