L'ultima release di ASP.NET MVC (Preview 2) fornisce alcune interessanti novità ed opportunità per gli sviluppatori ASP.NET. In particolare mi ha colpito molto la facilità di implementazione di meccanismi di routing che non siano più dipendenti dal framework MVC e che dunque possano essere facilmente integrati in progetti ASP.NET 'tradizionali'. Infatti, attualmente il framework Mvc è stato partizionato in tre assembly: il solito System.Web.Mvc ed i nuovi System.Web.Routing e System.Web.Abstractions.
Da un punto di vista pratico, uno degli usi sicuramente più ovvi delle funzionalità di routing riguarda la possibilità di realizzare qualcosa di alternativo all' Url Rewriting (Routing e Url Rewriting infatti non sono la stessa cosa (*)): tutto ciò di cui abbiamo bisogno è creare anzitutto una classe che implementi l'interfaccia IRouteHandler e quindi registrare nel Global.asax le nuove 'Routes' associate al nostro IRouteHandler. Vediamo un banale esempio di base:
using System.Web.Routing;
using System.Web.Compilation;
public class WebFormRouteHandler : IRouteHandler
{
public string VirtualPath { get; set; }
public WebFormRouteHandler( string virtualPath ) { this.VirtualPath = virtualPath; }
#region IRouteHandler Members
public IHttpHandler GetHttpHandler(RequestContext requestContext)
{
foreach (var value in requestContext.RouteData.Values)
{
requestContext.HttpContext.Items[value.Key] = value.Value;
}
IHttpHandler page = (IHttpHandler)BuildManager.CreateInstanceFromVirtualPath(this.VirtualPath, typeof(Page));
return page;
}
#endregion
}
Notiamo come l'unico metodo (GetHttpHandler) dell'interfaccia IRouteHandler prende in input il RequestContext (che nel mondo MVC viene solitamente acceduto tramite la proprietà ControllerContext del Controller). Al suo interno, ci sono tutte le informazioni di routing estratte dall'URL (proprietà RouteData), che andiamo a 'copiare' nell'HttpContext affinchè siano utilizzabili all'interno delle nostre WebForms.
Inoltre, nell'implementazione osserviamo l'utilizzo della classe statica BuildManager che ci permette di istanziare una nostra Page (che implementa l'interfaccia IHttpHandler) partendo dal path virtuale.
Analogamente a quanto avviene nel framework MVC, le Routes associate al nostro WebFormRouteHandler : IRouteHandler sono registrate nell'evento Application_Start del Global.asax:
using System.Web.Routing;
public class Global : System.Web.HttpApplication
{
public static void RegisterRoutes(RouteCollection routes)
{
var detailsHandler = new WebFormRouteHandler( "~/Details.aspx" );
routes.Add(new Route("category/{category}/item/{id}", detailsHandler));
}
protected void Application_Start( object sender, EventArgs e )
{
RegisterRoutes(RouteTable.Routes);
}
...
}
A questo punto siamo pronti!
Nelle nostre pagine ASPX recuperiamo i parametri contenuti nell'URL tramite la proprietà HttpContext.Items ["<key>"] (che esiste solamente nel ciclo di vita della singola pagina). Ad esempio:
protected void Page_Load( object sender, EventArgs e )
{
string categoryId = Context.Items["category"].ToString();
string ItemId = Context.Items["id"].ToString();
...
}
(*) Il routing non effettua un rewriting dell'URL vero e proprio, bensì costituisce un meccanismo 'bidirezionale' di generazione di URL.
Technorati tags: ASP.NET MVC