Uno sguardo a ASP.NET Dynamic Data – parte 1

Una delle novità presenti nella SP1 di .NET 3.5 sono i Dynamic Data (DD), o meglio ASP.NET Dynamic Data. In estrema sintesi i DD consentono di generare un sito web completo partendo da un modello dei dati. Vi è mai capitato di dover costruire un’applicazione web in poco tempo, niente di eccezionale, solo per poter permettere di fare operazioni di interrogazione e modifica su una sorgente dati?

Bene, i DD sono pensati proprio per questi scenari: si parte da un modello dei dati costruito con LINQ to SQL o Entity Framework (ma non solo..) e su questo, delle pagine aspx fungono da template generici, essendo in grado di capire quali tabelle sono presenti nel modello dei dati, di capire come sono fatte e di visualizzarle così come renderle modificabili. Esiste quindi un template unico (condiviso da tutte le tabelle) per le operazioni tipiche che su queste potremmo fare (interrogazione, modifica etc).

Un altro aspetto importante riguarda il motore di routing su cui si basano, che consente di non legare l’url che chiamiamo nel browser per richiedere una specifica pagina a dove la pagina fisica risieda oppure a come questa si chiami. Inoltre è possibile modificare il comportamento del motore di routing tramite delle regole, in un unico punto, senza dover modificare alcunché nelle singole pagine e come queste si richiamino tra di loro.

Partiamo con un semplice esempio:

Da Visual Studio 2008 SP1 ( oppure con Visual Web Development Express 2008 SP1) scegliamo uno dei due nuovi template disponibili:

image

Scegliamo Dynamic Data Web Application, perché pensiamo di generare il modello dei dati con LINQ to SQL, se volessimo usare Entity Framework dovremmo scegliere Dynamic Data Entities ….

Date ora un rapido sguardo al progetto generato che contiene la cartella DynamicData, che a sua volta contiene i template che vi dicevo sopra, in particolare guardate la sottocartella PageTemplates che contiene i template usati dai DD. Qui trovate una descrizione delle pagine incluse di default.

E’ interessante anche il folder FiledTemplate in cui trovate come viene eseguito il rendering di uno specifico tipo, ad esempio il file Boolean.ascx e Boolean_Edit.ascx contengono il codice che viene generato a runtime tutte le volte che si deve generare la parte di pagina che visualizza una colonna del database di tipo boolean e, come avrete capito, il comportamento cambia se siamo in fase di visualizzazione piuttosto che editing del campo. Quindi, in un unico punto, è stato centralizzato il comportamento per la visualizzazione e la modifica dei singoli campi delle tabelle del database. Posso modificare il codice qui e vedere le modifiche apportate ogni volta che viene visualizzata una colonna che fa riferimento ad un campo boolean su db, di una qualsiasi pagina che venga renderizzata. I DD hanno anche un meccanismo che consente di fare un po’ il contrario: di specificare cioè che un particolare campo boolean, di una particolare tabella sia visualizzato in modo completamente diverso che dagli altri. Vedremo meglio questo meccanismo di estendibilità in un altro post.

Per ora procediamo oltre e aggiungiamo un modello dei dati basato su LINQ to SQL. Dal menù: Add new Item, quindi scegliamo Linq to SQL Classes, “agganciamo” il nostro database Northwind, o quello che preferite, e senza preoccuparcene troppo facciamo drag & drop di tutte le tabelle, alla fine ci troviamo più o meno nella situazione in figura:

image

Nella figura trovate evidenziati il folder DynamicData e il file del modello dei Dati Northwind.dbml.

Ora andiamo nel file global.asax, semplicemente scommentiamo la riga di codice in cui informiamo i DD del nostro modello, “registrandolo” e aggiungendo il DataContext che mi ha creato il designer, NorthwindDataContext , imponendo a true l’attributo ScaffoldAllTables, che in soldoni dice ai DD di utilizzare tutte le tabelle del mio modello dei dati. E’ doveroso ricordare, come il commento nella stessa pagina global.asax ricorda, questa può non essere la cosa migliore da fare, ma per ora, per il mio esempio, può andare.

Premendo F5 vediamo la nostra applicazione già bella che fatta. In figura vedete la prima schermata che mostra l’elenco delle tabelle

image

Per renderci conto di quanto sia potente il meccanismo di discovery del modello dei dati usato dai DD, premiamo il link che ci porta alla tabella Products, la pagina list.aspx che viene invocata, è un template completamente generico, è in grado di visualizzare correttamente la tabella Products.

Nella seguente figura, ho evidenziato gli aspetti notevoli che i DD ci mettono a disposizione gratuitamente:

image

I DD si accorgono :

  • che la tabella Products ha una relazione di foreign-key con la tabella Category ed invece di mostrarci l’ID della Categoria, ad esempio 1 per il primo prodotto, ci mostra il nome della categoria, cioè Beverages. Potente, no! Lo stesso vale per Supplier.
  • Mettono a disposizione un menù per fare operazione di filtraggio: guardate Discontinued, Category, Supplier: che è generato dinamicamente in base a quali campi boolean e alle relazioni foreign-key presenti nella tabella prodotti.
  • Seguendo i link Edit, Delete e Details si giunge a delle pagine che servono proprio per le operazioni suddette, che ovviamente sono generate a partire dagli altri template, anch’essi generici e adattabili a qualsiasi tabella.

Il tutto finora semplicemente scrivendo una riga di codice nel file global.asax.

Il Routing

Se torniamo al file global.asax, noterete come viene generato l’url per navigare l’applicazione web generata:

image

L’url viene composto con il nome della tabella e il nome delle action, a cui viene aggiunta l’estensione aspx. Ora cos’è l’action ? Possiamo pensare alle action come alle azioni eseguite sulla pagina dall’utente. Esiste l’enum PageAction che contiene le action usate di default dai DD. Con un esempio si potrebbe dire che se l’utente clicca sul link Edit, per modificare come è fatto un singolo prodotto, la pagina esegue la relativa action PageAction.Edit e il motore di routing invoca la corrispondente pagina, nell’esempio sopra sarà dunque la pagina Edit.aspx, che trovate nel folder dei template in Page templates.

Per renderci conto di quanto sia flessibile il motore di routing, possiamo provare ad aggiungere due nuove regole. Le regole seguenti valgono solo sulla tabella “Supplier”.

image

Attenzione : le regole hanno una precedenza, quindi dobbiamo applicare queste due regole prima di quella presente di default che è più generica. Questa regola agisce quando scegliamo la tabella Supplier (durante la navigazione ). In questo caso sia che l’utente scelga di selezionare la lista di tutti i supplier (PageAction.List), che scelga di selezionare il singolo supplier (PageAction.Details), la pagina che la visualizza sarà la ListDetails.aspx (anche questa è una delle 4 pagine presenti di default nel folder Page Templates). Nella definizione della regola ViewName è il nome della pagina aspx (senza estensione) che deve farne il rendering. Mentre in verde vedete l’url che apparirà nella address bar del browser, che può essere quello che volete, in questo caso ho semplicemente rimosso l’estensione “.aspx” alla fine dell’url.

Conclusione

I DD vanno ad arricchire le funzionalità delle WebForms, offrendo un framework per realizzare applicazioni web data-driven. In questo post abbiamo visto brevemente come iniziare ad usarli vedendo i principi di base del loro funzionamento.

I DD offrono comunque un meccanismo che permette molte forme di personalizzazione, permettono di usare dei template particolari per fare il rendering di campi specifici di una tabella usando ad esempio i controlli dell’ AJAX Control Toolkit o di terze parti ad esempio per selezionare un calendario, oppure uno slider per decidere una quantità numerica. Le pagine degli ASP.NET Dynamic Data sono già pensate per sfruttare i controlli ASP.NET AJAX.

Altri attributi consentono di impostare delle regole di validazione sul modello dei dati, ad esempio posso impostare tali regole direttamente sulle proprietà delle classi generate da LINQ to SQL, creando delle partial class. Questo meccanismo consente di accentrare le regole di validazione, che poi “fluiscono” nella UI e valgono in qualsiasi pagina web si faccia riferimento a quella specifica classe...

Spero di avere stuzzicato la vostra curiosità , almeno per chi non ha ancora avuto modo di provare i nuovi ASP.NET Dynamic Data.

MSDN library ASP.NET Dynamic Data

www.asp.net/dynamicdata/