Il secondo tipo di progetto web disponibile in VS2010 è di tipo Asp.Net MVC2, evoluzione della struttura MVC1 già presente come addin per VS2008. La scelta di usare MVC2 al posto di Web Forms è dovuta ad alcuni fattori fondamentali:
- Controllo completo sul markup HTML generato
- Separazione tra logica e visualizzazione (codice HTML)
- Possibilità di creare unit test per le funzionalità della pagina
Ci occuperemo degli unit test in una lezione apposita, più avanti, per ora concentriamoci sui rimanenti due punti.
Le Web Form, oltre a generare molto traffico HTTP (come visto precedentemente), permettono un controllo limitato sul codice HTML generato dai controlli più complessi, come ad esempio le griglie.
Questo comporta molti problemi soprattutto in siti che devono soddisfare requisiti di accessibilità; le web form infatti sono eccezionali per chi ha una limitata conoscenza di HTML, perchè si occupano di fare il lavoro "sporco", ma forniscono controllo limitato su cosa verrà veramente scritto nella pagina.
Asp.Net MVC2 è invece basato sull'oramai consolidato pattern Model-View-Controller in cui il Modello rappresenta la logica applicativa, il controller è preposto a contenere le logiche delle pagine, ed infine le varie View hanno il solo scopo di renderizzare il contenuto.
Una trattazione completa di MVC2 esula dal contesto di questa guida (per iniziare si può leggere la nostra Guida ASP.NET MVC), ma è interessante osservare cosa il wizard di creazione progetto ha inserito di default nel nostro sito.
Come si vede in figura, esistono tre cartelle molto speciali: Models
, Controllers
e Views
. Mandando in esecuzione il sito si viene portati ad una pagina di default di benvenuto, ma per capire cosa succede si deve controllare il file Global.Asax
dove è stato impostato il routing:
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = "" }// Parameter defaults
);
}
Il concetto di routing è fondamentale per un progetto MVC (ed è comunque presente anche nelle web form), perche stabilisce un mapping tra una url ed un controller, che poi al suo interno si occuperà di gestire il Model e le View.
In questo caso la route è composta da tre parti: controller, action e id, con i rispettivi valori di default. Quando si effettua una richiesta sulla radice del sito, grazie ai valori di default è come se si chiedesse l'url /home/index/
(ad es. http://localhost:1399/home/index
), in cui il controller è home
, la action è index
e l'id non è presente.
Il motore di asp.NET MVC2 elabora l'url, la scompone nelle parti base appena viste e procede in questo modo: cerca una classe che si chiama HomeController e che eredita dalla classe base Controller:
[HandleError]
public class HomeController : Controller
{
public ActionResult Index()
{
ViewData["Message"] = "Welcome to ASP.NET MVC!";
return View();
}
public ActionResult About()
{
return View();
}
}
Una volta identificato il controller, viene cercata una funzione del controller il cui nome è eguale alla parte Action dell'url e che accetta i parametri specificati. In questo caso l'azione scelta è la Index
e dato che il parametro id
non è presente viene invocata la funzione Index()
senza parametri.
Le azioni in genere interagiscono con database, logiche applicative ed hanno il compito di decidere cosa visualizzare. Per passare i dati alla View, un dizionario chiave-valore chiamato ViewData
; una volta che tutti i dati sono stati inseriti la funzione restituisce il valore View()
il cui significato è: attiva la vista di default associata al controller.
La cartella View
contiene tutte le viste, la vista di default è in una sottocartella chiamata come il controller ed ha lo stesso nome della action con estensione aspx
. Quello che viene fatto è quindi mostrare la vista /View/Home/Index.aspx
a cui è stato passata una stringa nel ViewData
>.
Anche per MVC2 esiste il concetto di master page, ma l'aspetto veramente importante è che nella vista aspx non sono presenti controlli lato server che renderizzano codice, ma solo il controllo container che permette di stabilire dove inserire i dati rispetto alla master page.
Il contenuto di una vista è quindi una serie di tag HTML inframezzati da istruzioni che prendono i dati dal ViewData e li inseriscono nella pagina grazie ai tag <%= %>
<h2><%= Html.Encode(ViewData["Message"]) %></h2>
<p>To learn more about ASP.NET MVC visit <a href="http://asp.net/mvc" title="ASP.NET MVC Website">http://asp.net/mvc</a>.</p>
Lo scopo di MVC è separare completamente il codice che esegue la logica della pagina (gestito dal controller) dalla parte di rendering della pagina (la view), permettendo nel contempo di eseguire unit test nel controller al di fuori del contesto di IIS. Sebbene ad un primo impatto si possa pensare di essre tornati allo spaghetti code di asp classico, dato che la vista utilizza un misto di HTML e istruzioni, in realtà non è assolutamente cosi, dato che la vista non deve contenere nessuna logica, ma semplicemente posizionare nella pagina il contenuto elaborato dal controller.
Quindi, mentre le Web form permettono di realizzare pagine con poco sforzo anche da chi ha una scarsa conoscenza di HTML, la struttura MVC2 necessita di maggiore lavoro per creare una pagina, ma garantisce un controllo più fine ed è dedicata a chi ha una buona conoscenza di HTML e vuole il controllo completo del contenuto.
L'accoppiata con jQuery permette poi di spostare alcune funzionalità sul browser, diminuendo il traffico con il server ed aumentando molto la scalabilità degli applicativi, permettendo l'interazione dei controlli anche con servizi WCF o asmx classici.