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

Spark, un View Engine alternativo per Asp.Net MVC

Un view engine molto potente che rappresenta un'alternativa valida a WebForms e NVelocity
Un view engine molto potente che rappresenta un'alternativa valida a WebForms e NVelocity
Link copiato negli appunti

Il nuovo framework Asp.Net MVC (attualmente alla Preview Release 5), è stato progettato per offrire un alto grado di estensibilità: ogni suo componente può essere modificato o interamente sostituito. In molti casi, come per il motore di rendering delle viste, è addirittura possibile far convivere un sistema personalizzato assieme a quello di default, caretteristica che rende possibile utilizzare funzionalità personalizzate senza rinunciare a quelle offerte dal framework.

In questo articolo realizzeremo un catalogo dei prodotti, uno fra gli esempi più classici per MVC, utilizzando un view engine alternativo, Spark.

Cos'è Spark

Spark, creato e seguito da Louis DeJardin, è un view engine relativamente giovane ed in continuo sviluppo che offre un alto grado di innovazione rispetto ad alternative quali WebForms, Brail o NVelocity. Vediamo subito un esempio:

<ul>
  <li each='var p in ViewData.Model.Products'>
    ${Html.ActionLink[[ProductController]](c => c.Detail(p.ProductID), p.ProductName)}
  </li>  
</ul>

Questo codice visualizzerà una lista di prodotti (contenuti nella collection Products dell'oggetto ViewData) tramite una lista non ordinata <ul>. Il codice C# è perfettamente integrato nel markup HTML attraverso la direttiva each del tag <li>.

Spark offre inoltre la possibilità di sostituire i pesanti tag <%= %> con una alternativa molto più leggibile: ${}. Il codice racchiuso nelle parentesi graffe è infatti ancora C# e visualizzerà un link attraverso l'extension method ActionLink dell'oggetto Html. L'uso delle parentesi quadre ([[ e ]]) per i generics si rende necessario per evitare problemi con il markup HTML.

Per finire è possibile utilizzare anche la sintassi LINQ all'interno delle nostre pagine.

Le viste Spark sono compilate al primo accesso come avviene per le pagine Aspx, procedura che aumenta notevolmente i tempi di risposta rispetto a soluzione interpretate come NVelocity.

Fra le altre caratteristiche di Spark sono inoltre da sottolinare il supporto alle master pages, alle viste parziali e alle macro. Queste ultime in particolare sono molti utili per creare frammenti di codice riutilizzabile:

<macro name="ShowMessage" message="string">
  <div>
    ${message}
  </div>
</macro>

Questa macro visualizza a video un messaggio di testo e può essere richiamata con la sintassi:

${ShowMessage("Ciao, Spark!")}

Download e configurazione

Prima di cominciare la costruzione del catalogo, è necessario procurarsi Asp.Net MVC. Terminato il download è sufficiente seguire l'installazione guidata che si occuperà anche di integrare il framework all'interno di Visual Studio.

Poi scaricare gli assembly Spark. Sono disponibili sia un file .zip con gli assembly già compilati che il codice sorgente, accessibile anche attraverso SVN. Per lo scopo di questo articolo il primo file sarà più che sufficiente.

Inoltre, per chi non l'avesse ancora fatto, il consiglio è di aggiornare il Framework alla versione 3.5 Service Pack 1. Per l'esempio utilizzeremo il classico database Northwind, disponibile gratuitamente per il download e incluso nel file allegato a questo articolo.

Una volta installato il tutto, apriamo Visual Studio e creiamo un nuovo progetto scegliendo il template ASP.Net MVC Web Application, come linguaggio C# e la versione 3.5 del framework.

Configurazione di Spark

Dal file .zip (in cui troviamo anche la documentazione e alcuni progetti di esempio), estraiamo i file Spark.dll e Spark.Web.Mvc.dll e aggiungiamo al progetto appena creato un riferimento a questi due assembly.

È possibile configurare Spark attraverso una sezione dedicata del web.config o all'interno del file Global.asax. Per rendere il codice più pulito seguiamo il primo approccio, registrando la sezione <spark> all'interno di <configSection>.

<configSections>
  <section name="spark" type="Spark.Configuration.SparkSectionHandler, Spark" requirePermission="false"/>
</configSections>

<spark>
  <compilation debug="true">
    <assemblies>
      <add assembly="Microsoft.Web.Mvc" />
      <add assembly="System.Web.Routing, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
    </assemblies>
  </compilation>
  <pages>
    <namespaces>
      <add namespace="System"/>
      <add namespace="System.Collections.Generic"/>
      <add namespace="System.Linq"/>
      <add namespace="Microsoft.Web.Mvc"/>
      <add namespace="System.Web.Mvc"/>
      <add namespace="System.Web.Routing"/>
      <add namespace="Esempio.Models" />
    </namespaces>
  </pages>
</spark>

Esaminiamo le impostazioni più importanti:

la sezione <compilation> si occupa di definire i parametri legati alla compilazione delle nostre viste, ad esempio se compilare in modalità debug o release, e dell'importazione degli assembly necessari.

nella sezione <pages> possiamo invece elencare i namespace da importare di default nelle viste; da notare che fa parte dell'elenco anche Esempio.Models, il namespace che conterrà le classi LINQ To SQL.

Una volta configurato Spark nel file web.config non resta che aggiungerlo alla lista dei view engine di Asp.Net MVC all'interno del file Global.asax:

protected void Application_Start()
{
    .....
    ViewEngines.Engines.Add(new SparkViewFactory());
    .....
}

Con questi pochi e semplici passaggi Spark è configurato e pronto ad essere utilizzato assieme al motore WebForm predefinito di MVC. Ogni volta che un controller richiamerà una vista, infatti, Asp.Net si preoccuperà automaticamente di selezionare il view engine più adatto al rendering.

Database e controller

La configurazione dell'applicazione per l'accesso ai dati è relativamente semplice. Si tratta infatti soltato di aggiungere una nuova classe LINQ To SQL al progetto e di trascinare dal database Northwind la tabella Products all'interno dello spazio di lavoro, lasciando generare al designer di Visual Studio le classi e le funzioni di cui abbiamo bisogno per l'accesso ai dati.

Senza modificare il controller predefinito HomeController.cs, aggiungiamone un altro chiamato ProductsController.cs. Le azioni implementate saranno solamente tre:

[HandleError(View = "Error", Master = "Site")]
public class ProductsController : Controller
{
  public ActionResult Index()
  {
    return RedirectToAction("List");
  }

  public ActionResult List()
  {
    using (NorthwindDataContext context = new NorthwindDataContext())
    {
      var products = context.Products.Take(5).ToList();

      return View("List", "Layout", products);
    }
  }

  public ActionResult Detail(int? id)
  {
    using (NorthwindDataContext context = new NorthwindDataContext())
    {
      var product = context.Products.Single(p => p.ProductID == id);

      return View("Detail", "Layout", product);
    }
  }
}

Index è l'azione di default che tuttavia non svolge nessuna operazione, passando il controllo a List, che estrae una lista di cinque prodotti dal database e li passa alla relativa vista. L'altra azione, Detail, mostra il dettaglio di un singolo prodotto basandosi sul suo ID.

È interessante notare, a sostegno di quanto detto poco fa sulla possibilità di utilizzare più view engine contemporaneamente, che la vista e la master page specificate nell'attributo [HandleError] sono due pagine ASP.NET classiche e non due viste realizzate con Spark.

Creazione delle viste

Passiamo ora alla creazione delle tre viste principali di cui avremo bisogno: List.spark, Detail.spark e Layout.spark. Quest'ultima sarà la master page della sezione prodotti.

Layout.spark è un meccanismo molto semplice e consiste in una copia della master page Site.Master che viene creata dal wizard di Visual Studio per i siti web MVC. L'unico cambiamento di rilievo riguarda il tag ContentPlaceHolder che in Spark diventa:

<use content="body" />

List.spark si compone invece di un tag <content>, equivalente di <asp:content>, che indica il contenuto del tag <use> dichiarato nel layout.

<content name="body">
  <viewdata model="List[[Product]]" />
  
  <h1>Prodotti</h1>
    
  <if condition="ViewData.Model != null && ViewData.Model.Count > 0">
  <ul>
    <li each="var p in ViewData.Model">
      ${Html.ActionLink[[ProductsController]](c => c.Detail(p.ProductID), p.ProductName)}
    </li>
  </ul>
  </if>
  <else>
    Nessun prodotto.
  </else>
</content>

Il tag <viewdata> ci permette di dichiarare il tipo delle variabili presenti nell'oggetto ViewData, un po' come avviene nel code behind delle pagine ASP.NET attraverso l'uso dei generics:

public partial class List : ViewPage<List<Product>> { ... }

Questo meccanismo, sebbene un po' ridondante e prolisso (dovremo dichiarare il tipo per ogni proprietà), è molto potente e ci permetterà nel resto della view di gestire gli oggetti in modo fortemente tipizzato.

Il tag <if> rappresenta una condizione che deve essere verificata perchè il codice al suo interno sia eseguito. Nella nostra pagina verifichiamo che la lista dei prodotti estratta dal database non sia vuota, per poi visualizzarla attraverso una lista non ordinata <ul>.

Se non fossero presenti prodotti il codice salterebbe al contenuto del tag <else>. Per ogni prodotto viene generato un link alla pagina Detail con il meccanismo ActionLink già descritto all'inizio dell'articolo.

Non scendiamo nel particolare del codice della vista Detail.spark, che è molto semplice e non dovrebbe presentare particolari difficoltà di comprensione.

Purtroppo attualmente non sono disponibili template o plugin per facilitare lo sviluppo di pagine Spark all'interno di Visual Studio: dovremo quindi accontentarci di creare dei file di testo generici a cui cambiare l'estensione.

È comunque possibile, tuttavia, migliorare l'esperienza di scrittura del codice associando l'estensione .spark al syntax highlighting per HTML, ottenendo almeno il supporto Intellisense per i tag. Per fare questo è sufficiente selezionare la voce Opzioni nel menu Strumenti e, dopo aver spuntato la casella Mostra tutte le impostazioni, aprire la voce Editor di Testi selezionando Estensioni file. A questo punto aggiungete per l'estensione .spark l'editor HTML.

Figura 1. Impostare l'IntelliSense
Impostare l'IntelliSense

Conclusioni

Abbiamo visto come espandere le funzionalità di Asp.Net MVC con Spark, un view engine caratterizzato da un markup fortemente integrato nell'HTML della pagina.

Pur offrendo molte funzionalità e un buon livello di innovazione Spark ha anche qualche svantaggio:

  • la compilazione richiede l'esecuzione del codice in Full Trust, limitazione molto forte per gli spazi web condivisi. Una possibile soluzione consiste nella precompilazione delle viste, descritta in questa pagina della documentazione ufficiale;
  • VB.Net non è attualmente supportato ed è pertanto possibile utilizzare soltanto C#;
  • il supporto all'interno di Visual Studio è per il momento molto limitato;

Possiamo trovare maggiori informazioni nella documentazione ufficiale di Spark e presso il gruppo di discussione spark-dev dove è possibile ottenere supporto ed eventualmente partecipare allo sviluppo del programma.

Ti consigliamo anche