ASP.NET MVC & Microsoft Chart Controls

7 novembre 2011

Ultimamente mi sono concentrato molto sull’utilizzo di ASP.NET MVC per lo sviluppo di un progetto abbastanza grosso, tra le varie cose è sorta l’esigenza di poter utilizzare uno strumento per la generazione di grafici di vario tipo.

All’inizio la mia scelta è ricaduta su “Libero API for Fusion Charts”, un prodotto fatto davvero molto bene e che offre la possibilità di implementare diverse tipologie di grafico (tante!). Nonostante le sue caratteristiche ho dovuto mettere da parte questa libreria in quanto legata all’utilizzo del componente Flash (sempre questioni di legacy).

Alla fine ho optato per la soluzione che poi si è rivelata anche la migliore (e ancora mi chiedo perché non ci ho pensato prima?). La scelta è ricaduta su “Microsoft Chart Controls”.

Partiamo dal presupposto che questo prodotto non si presta bene, se non dopo qualche piccolo accorgimento, per essere utilizzato con ASP.NET MVC. Infatti nasce per funzionare principalmente all’interno di applicazioni Web Forms, la cui struttura è nettamente diversa da quella di un progetto MVC. Essendo il chart un controllo Server, necessita di una pagina web di tipo System.Web.UI.Page in cui poter essere posizionato, sappiamo bene che in una pagina MVC non è possibile inserire controlli di questo tipo.

Oggi vorrei spiegarvi come configurare il vostro progetto MVC perché i Microsoft Charts possano funzionare correttamente e senza alcun tipo di problema.

Prima di tutto è necessario estendere le funzionalità dell’oggetto Page perché possa occuparsi anche del disegno dei grafici ms. Lo facciamo realizzando un helper come nell’esempio che segue:

namespace MvcApplication.Helpers
{
	public static class HelperCharts
	{
		public static void RenderChart(this Page page, System.Web.UI.DataVisualization.Charting.Chart chart)
		{
			var writer = new HtmlTextWriter(page.Response.Output);
			chart.RenderControl(writer);
		}
	}
}

Chiaramente le istruzioni che abbiamo scritto sono poche e semplici, ritengo in ogni caso che lavorare in questo modo garantisce una migliore leggibilità e pulizia del codice  e, soprattutto per quanto riguarda MVC, rispetto delle regole imposte dal pattern.

Completato il metodo dobbiamo assicurarci che tale funzionalità sia poi disponibile in tutte le Views e che la gestione dei Charts possa essere correttamente eseguita dal .Net Framework, per tale motivo è necessario il file web.config:

<configuration>
	<appSettings>
		<add key="ChartImageHandler" value="storage=file;timeout=20" />
	</appSettings>
	<system.web>
		<httpHandlers>
		<add path="ChartImg.axd" verb="GET,HEAD,POST" 
			type="System.Web.UI.DataVisualization.Charting.ChartHttpHandler, 
				System.Web.DataVisualization, Version=4.0.0.0, 
				Culture=neutral, PublicKeyToken=31bf3856ad364e35"
	        	validate="false" />
		</httpHandlers>
		<pages>
			<namespaces>
				<add namespace="MvcApplication.Helpers" />
			</namespaces>
		</pages>
	</system.web>
</configuration>

Come da documentazione è necessario aggiungere la chiave ChartImageHandler per definire le modalità di generazione del grafico (considerando che questo alla fine non è altro che un’immagine). Nell’elenco degli HttpHandlers è necessario configurare la risorsa utilizzata per la generazione dei grafici e, per concludere, volendo rendere visibile la funzione precedentemente scritta (RenderChart) in tutte le viste senza dover effettuare una import in ogni pagina del namespace, aggiungiamo all’elenco dei default namespaces anche quello in cui risiede il metodo da noi implementato.

In seguito possiamo realizzare un DTO fatto in questo modo:

namespace MvcApplication.Models.DTO
{
	public sealed class SampleDTO
	{
		public Chart Chart { get; private set; }

		public SampleDTO(Chart chart)
		{
			Chart = chart;
		}
	}
}

Possiamo ora creare un controller di esempio che dispone di un’Action che restituisce il DTO precedentemente realizzato:

namespace MvcApplication.Controllers
{
	using MvcApplication.Models.DTO;
	public class SampleController : Controller
	{
		[HttpGet] public ActionResult GetSampleChart()
		{
			Chart chart = new Chart();
			// Configure Chart...
			SampleDTO sampleDTO = new SampleDTO(chart);
			return View(sampleDTO);		
		}
	}
}

E per concludere si passa alla View che si presenta come nell’esempio:

<%@ Page 
	Title="Sample" 
	Language="C#" 
	MasterPageFile="~/Views/Shared/Shell.Master" 
	Inherits="System.Web.Mvc.ViewPage<MvcApplication.Models.DTO.SampleDTO>" %>
<h2>Chart Sample</h2>
<div>
<% 	Page.RenderChart(Model.Chart); >
</div>

Con poche righe, abbiamo realizzato quanto necessario per poter sfruttare in modo corretto e pulito i Microsoft Charts nel nostro progetto MVC.

Enjoy!

Quando un Design Pattern ti evita l’esaurimento nervoso

22 ottobre 2010

Tempo fa’ (tanto tempo), un mio amico per cui nutro grandissima stima, mi ha consigliato un libro molto interessante in cui, molti dei Design Pattern che oggi si utilizzano, vengono spiegati ed approfonditi cosi attentamente da risultare praticamente impossibile non capire cosa c’è scritto.

Sto parlando di un libro intitolato Patterns of Enterprise Application Architecture di Martin Fowler, uno dei migliori acquisti che abbia mai fatto!

Oggi, a distanza di moltissimo tempo (circa 6 mesi), ho rimesso mani su un progetto di cui, io stesso, l’autore, ne avevo dimenticato completamente l’esistenza. Un sistema abbastanza complesso per l’elaborazione di dati provenienti da diverse sorgenti, un contenitore di informazioni allo stato puro, un “Tracking System”, un fattorino, un sistema di lavaggio, in somma una miriade di funzionalità, si documentate (da un analisi allegata sempre scritta da me), ma… come fai a distanza di 6 mesi a metterci mani per modificare il codice?

Mi collego al magnifico (si fa’ per dire, prenderei volentieri a pugni colui che ha inventato questo sistema di versioning) Microsoft Visual Source Safe aziendale e scarico tutto il progetto, durante l’operazione di Download inizio già ad avere la pelle d’oca, i file sono tantissimi, ed inizio a pensare “Da dove devo iniziare?”.

Completato l’allineamento apro la Soluzione e SORPRESA!

Ritrovo un progetto che mi ricorda tanto ASP.NET MVC (peccato che lo stesso progetto è realizzato, per questioni di Legacy, in .Net Framework 2.0) per la sua struttura interna:

  • Content
  • Models
  • Views

La mia prima reazione? Un Sorriso, immaginavo di aver messo insieme diverse tecniche e utilizzato molteplici strumenti per realizzare qualcosa di molto molto facile (data la futura previsione di introdurre miei colleghi allo sviluppo dello stesso). Provo ad espandere la voce Models e capisco subito con cosa ho a che fare guardando semplicemente la ripetizione dei suffissi con cui i nomi file si alternano in questa cartella:

  • Entity1.cs
  • Entity1TableGateway.cs
  • Entity2.cs
  • Entity2TableGateway.cs
  • Build.bat

Figo! Non ricordavo di aver usato un Design Pattern (sarebbe stato anormale il contrario in un progetto del genere), la cosa che non capisco è quel Build.bat finale, la cosa simpatica è il commento che 6 mesi prima ci ho lasciato dentro!

/*
 *	Ciao Roberto! Sono sempre io... Roberto, cioè sono tu!
 *	Immaginavo non ti ricordassi di me, ti scrivo, in 
 *	questo commento per darti una fantastica notizia, 
 *	ti basta eseguire questo batch, se hai modificato 
 *	la struttura delle tablle nel db, per rigenerare
 *	l'intera base dati sotto .Net con un misto Design 
 *	Pattern (TableGateway e Transaction Script)
 *	
 *	Tuo, tu.
 */

Si, mi sono commosso davvero tanto leggendo queste parole…. ho riso come un pazzo per 5 minuti! La bellezza dei Design Pattern la si nota per due motivi:

  1. Te ne ricordi facilmente il funzionamento.
  2. Quando hai capito come funziona la giostra, sei in grado di creare la catena di montaggio che la costruisce!

JSON e .Net Framework 2.0

18 ottobre 2010

Nonostante il .Net Framework sia in continua evoluzione, può sicuramente capitarci di dover lavorare con una versione che non sia proprio l’ultima, il cliente richiede particolari specifiche che viaggiano in concomitanza con l’evolversi del web 2.0 ed allo stesso tempo ci impone delle restrizioni, a quel punto il nostro compito non è solo quello di sviluppare il progetto ma, prima ancora, scegliere le specifiche con cui realizzarlo, le tecnologie a supporto di cui si può usufruire realizzando cosi la nostra cassetta degli strumenti personalizzata.

Un esempio pratico può essere Ajax, questa tecnologia riscuote successo da pochi anni a questa parte (soprattutto da quando c’è stato l’avvento del Web 2.0) e prendendo ad esempio il .Net Framework 2.0 possiamo facilmente capire che a quel tempo, l’idea che questa tecnologia potesse avere successo non era stata prevista data la totale mancanza di strumenti di supporto per gestirla (problema totalmente risolto a partire dalle versioni successive del framework). In questo senso ci vengono in aiuto librerie esterne che possono agevolarci di molto il lavoro che dobbiamo fare.

Oggi vi parlo di Json.NET – James Newton-King, un prodotto validissimo per l’elaborazione di dati lato Server in formato JSON, sono arrivato a tale soluzione partendo dalle mie necessità principali, cioè la completa compatibilità con il .Net Framework 2.0, la possibilità di mappare oggetti molto facilmente e soprattutto una buona documentazione (nessun prodotto è totalmente buono se non è accompagnato da una documentazione altrettanto soddisfacente!).

Dal sito ufficiale è possibile scaricare la libreria in base alla versione del Framework che si deve utilizzare, per il .Net 2.0 ho utilizzato Newtonsoft.Json.Net20.dll.

L’uso è molto semplice, basta referenziare la libreria all’interno del proprio progetto e tramite using è possibile richiamarla per poterne sfruttare le funzionalità. L’esigenza di utilizzare questa libreria è nata da un preciso problema, ho un oggetto molto complesso formato da diverse Proprietà pubbliche, di queste alcune sono calcolate, mentre altre sono dati veri e propri, il mio obiettivo è implementare una comunicazione Client (Web Browser) / Server di questo tipo:

JSON-SERVER-TO-CLIENT

In pratica voglio che un oggetto che sul server è mappato e contiene X proprietà, quando viene inviato al client come risposta JSON ad una richiesta AJAX, contenga un numero di proprietà diverso, numero che varia in base ai campi, dello stesso, che decidiamo di inviare. Nello schema si può notare come, tramite conversione, voglio che la Property 2 non arrivi nella risposta Ajax. Con la libreria Json.Net questa operazione diventa molto semplice! Prima di tutto dobbiamo creare il nostro OBJECT facendo attenzione alle specifiche di ogni proprietà:

using System; 
using Newtonsoft.Json;

namespace MyApplication.Data 
{ 
    public class MyObject
    {
    	  public int Property1; 
    	  [JsonIgnore]
    	  public int Property2; 
    	  public int Property3; 
    }
}

[ad#ad-lungo]

Il codice è molto chiaro, ho specificato un attributo per la Property2 che si chiama JsonIgnore e serve appunto per fare in modo che durante la conversione dei dati, questa proprietà non venga mappata. Comportamenti del genere sono molto frequenti se gli oggetti con cui abbiamo a che fare sono collegati tra di loro, analizziamo un oggetto più complesso per capire ancor meglio come intervenire:

JSON-SERVER-TO-CLIENT-2

In questo caso vogliamo fornire in Output le informazioni sull’utente, di questo i Ruoli non vogliamo che siano visualizzati per una particolare specifica.  Risulta utile mappare l’oggetto e specificare l’attributo perché se da un lato è semplice, dall’altro offre anche un codice auto-documentato in cui è facile intuire che si sono applicate determinate regole per una particolare esigenza. Supponendo di avere una Lista di ruoli all’interno del nostro oggetto utente, applicare la modifica risulterà molto semplice:

...
[JsonIgnore]
public List Ruoli 
{
    get { ... }
    set { ... }
}

In contesti ancor più ampi l’uso di tali pratiche durante la progettazione dei nostri oggetti risulta molto utile per un risultato finale di qualità, per esperienza diretta posso assicurarvi che quando la logica è davvero molto complessa ed i nostri oggetti espongono proprietà al cui interno si racchiudono particolari logiche che richiedono svariate risorse (es. Sql Server), sfruttare gli attributi in questo modo ci permette di ridurre drasticamente la stessa elaborazione dei dati e delle richieste.

Utopia dei database relazionali

28 settembre 2010

Più vado avanti e più mi rendo conto che il “Database Relazionale” per sua stessa definizione non esiste più, o almeno, la moda è quella di realizzare una base dati e di questa, la parte del nome che ha più importanza è proprio base, cioè niente di più che uno strumento per il salvataggio delle informazioni.

Vi starete chiedendo: ma tu che problema hai? Io ho diversi problemi ed oggi ve ne espongo qualcuno!

Allora, il mio lavoro non consiste solo nella progettazione e realizzazione di software, molte volte, in casi estremi quando nemmeno gli stessi dirigenti plurilaureati che si presentano dicendo

“Salve, io sono un espertissimo nell’elaborazione dati”

riescono a risolvere, forniamo al cliente supporto per la gestione dei database proprietari di cui proprio non riescono a capirci nulla. Capita spesso che venga acquistato un software da altre aziende che forniscono l’RDBMS spacciato per RELAZIONALE insieme al software atto alla sua manutenzione, la maggior parte delle volte, il cliente chiede sempre qualcosa in più relativamente allo stesso, tipo reports complicati, quadramenti, conteggi, roba che il Tool offerto per il Management non è in grado di offrire.

Qui interveniamo noi che forniamo supporto come CED (Centro Elaborazione Dati), ci infiltriamo in questi complessi database e tiriamo fuori le informazioni che servono (le più svariate e complesse query che il mondo possa conoscere, delle volte il cliente è cosi al punto tale da chiedere cose cosi complesse da non capirci nemmeno lui nulla mentre cerca di farci capire che vuole).

Il problema diventa inquietante quando per la prima volta abbiamo a che fare con la mappa della base dati.

Con il caro PAINT ho disegnato quelli che sono i tre tipi di RDBMS con cui sono abituato a lavorare, ci tengo a sottolineare RDBMS perché questi database che vi sto per presentare, vengono spacciati e garantiti come TALI, andando in ordine di stress e trauma post-job a cui si è sottoposti per analizzarli.

 

La RETE

La Rete

Questo tipo di Database per definizione è una RETE LAN adattata a base dati, si presenta come una struttura Figlia dei Fiori in cui ogni Tabella è amica, parente, madre e padre di tutte le altre che la circondano. La sua stessa composizione è indice dell’insicurezza del suo creatore, non sicuro di poter collegare tutto tramite una semplice relazione, ha deciso di creare una rete le cui caratteristiche delle volte spaventano chiunque si avvicini. Il motto per lavorare con questi database è:

Le vie del signore sono infinite.

L’INCOGNITA

L'incognita

Le tabelle appaiono timide ed introverse, non amano comunicare tra loro, ne tantomeno si impegnano per rendere la vita del DBA facile, per poter capire quali siano i collegamenti è necessario interrogarle una ad una, investigando sul loro carattere (colonne, nomi e tipi) ottenendo un risultato finale in tempi davvero molto lunghi. Per queste basi di dati vale un simpaticissimo commento letto in un articolo:

// Questo codice lo conosco solo io e DIO. 
Qualche tempo dopo...
// Questo codice ora lo conosce solo DIO.

Il senso della frase, relativa al contesto sviluppo codice, penso possa valere anche per queste situazioni.

UTOPIA

Utopia

Lettori ecco a voi quello che un database [ garantito RDBMS ] dovrebbe essere e che in realtà non è mai. Una base dati in cui ogni relazione e tabella sono progettate in modo tale da rendere chiara l’idea di quello che è il dato contenuto. Questo, è il tipo di database con cui non avrete mai a che fare!

CONCLUSIONI

Ad oggi non esiste un reale standard che definisca quali siano le regole per distinguere un Database Relazionale da un semplice contenitore di dati senza alcuna struttura e semantica, allo stesso modo una base dati non può essere definita relazionare solo perché presenta relazioni al suo interno.

Personalmente do una mia interpretazione per descrivere un database di questo tipo: un contenitore di dati con una struttura ben definita in cui tutto è al posto giusto, dai nomi delle tabelle alle loro relazioni, dai dati contenuti alle chiavi primarie scelte. Quando realizzo un progetto penso al database come ad un modulo indipendente dal resto dell’applicazione, modulo in cui devo essere in grado di operare senza essere a conoscenza di quella che è la parte applicativa, Stored Procedure, Chiavi Internet ed Esterne, Vincoli, Trigger etc. sono gli strumenti di cui mi avvalgo (se possibile, cioè se le tecnologie che utilizzo me lo permettono) per modellare l’intero sistema di gestione dei dati.

Ognuno ha il suo modo di lavorare, il contesto è una variabile imprescindibile in base a cui tutto cambia, seguendo queste linee guida realizzo le mie applicazioni ottenendo un vantaggio finale di non poco conto. Quando semantica e regole per una corretta rappresentazione vengono messe da parte, diventa un rischio per la mia salute psicofisica lavorare. Quando sono il diretto responsabile nella realizzazione di una base dati cerco di pensare a chi si troverà a dover interpretare il mio RDBMS e cerco di garantire un ingresso piacevole e senza troppi rischi  .

Tratto da: Come rovinare la vita di un DBA.