Nessun risultato. Prova con un altro termine.
Guide
Notizie
Software
Tutorial

ASP.NET Dynamic Data Filtering

Creare semplicemente filtri su qualunque colonna del database, senza toccare il codice
Creare semplicemente filtri su qualunque colonna del database, senza toccare il codice
Link copiato negli appunti

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.

Figura 1. Una maschera di ricerca realizzata con i Dynamic Data Filtering
Una maschera di ricerca realizzata con i Dynamic Data Filtering

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:

Figura 2. Lo schema del database
Lo schema del database

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:

Figura 3. Il controllo DynamicFilterForm
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 , 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:

Figura 4. Impostare il Data Source
Impostare il 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:

Figura 5. La nuova maschera di ricerca degli utenti
La nuova maschera di ricerca degli utenti

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:

Figura 6. La maschera di ricerca personalizzata
La maschera di ricerca personalizzata

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.

Ti consigliamo anche