Generazione di report in PDF con il framework .NET

March 4, 2010 17:49 by f.bernabei

Spesso all’interno di applicazioni abbiamo la necessità di generare report/stampe più o meno complesse, ed in particolare molte volte l’esigenza è quella di poter generare direttamente file in formato PDF, magari senza uscire dalla nostra applicazione o generare anteprime intermedie del risultato. Per farlo ci sono svariate soluzioni e strumenti, a partire dalle suite di reportistica professionali che permettono la generazione di report molto sofisticati, fino ad arrivare a librerie che permettono la sola generazione di documenti PDF a fronte però di una complessa programmazione e composizione da codice del documento finale.

Fortunatamente dalla versione 2.0 del framework .Net è possibile utilizzare un motore di reportistica derivato dai “Microsoft SQL Server Reporting Services” e distribuito con Visual Studio che è possibile utilizzare a tale scopo. Questo componente è in realtà un visualizzatore di report con estensione rdlc (variante “locale” dei file rdl utilizzati da Reposrting Services ed in pratica un formato xml che permette di descrivere template per i report) che permette l’esportazione dei report in svariati formati, tra cui anche il PDF; vedremo che con poche righe di codice è possibile pilotare direttamente la creazione di un PDF senza dover neanche aprire il visualizzatore, con il vantaggio rispetto ad altre soluzione di avere un editor visuale nativo in Visual Studio (nel nostro caso utilizzeremo Visual Studio 2008 SP1) per la definizione del report stesso (esistono inoltre strumenti esterni in grado di editare i file rdlc che rendono ipoteticamente possibile la personalizzazione dei report in un secondo tempo da parte dei clienti stessi).

In questo articolo quindi vedremo in “stile tutorial” i vari step necessari per la realizzazione di una semplice applicazione di test che alla pressione di un bottone esegua tutte le operazioni necessarie per generare un report e salvarlo in formato PDF.

Da bravi programmatori decideremo di rendere il report completamente slegato dalla base dati e gli forniremo quello di cui ha bisogno attraverso il passaggio di oggetti DTO creati ad hoc (o magari già presenti ed utilizzati all’interno della nostra applicazione). Nel progetto di esempio creiamo una classe che rappresenta un ipotetico articolo da stampare con il codice seguente:

   1: public class ReportDataDTO
   2: {
   3:     public int IdArticolo { get; set; }
   4:     public string Descrizione { get; set; }
   5:     public string Dettagli { get; set; }
   6:     public double Costo { get; set; }
   7:     public byte[] Immagine { get; set; }
   8: }

A questo punto possiamo aggiungere al progetto anche il file rdlc, cioè il template del report che utilizzeremo poi per la stampa. Per farlo basta aggiungere un nuovo item e scegliere dalla categoria “Reportings” il template per i report rdlc (nel mio caso l’ho chiamato ReportDemo.rdlc). Appena inserito il nuovo item si dovrebbe aprire automaticamente in Visual Studio 2008 l’editor dei report: dovreste avere qualcosa tipo:

Empty_rdlc
Il prossimo passo consiste nell’associare al template del report il DTO che sarà utilizzato come contenitore per lo scambio dei dati, nel nostro caso la classe ReportDataDTO precedentemente creata. Per farlo è necessario aggiungere una nuova sorgente dati (Menu Data –> Add New Data Source…) attraverso l’apposito wizard al quale dovremo dire di utilizzare un oggetto come sorgente dati e nella schermata successiva selezionare esplicitamente il tipo ReportDataDTO che abbiamo precedentemente creato.

wizard_dati_2
Una volta selezionata la nostra classe DTO possiamo premere direttamente il tasto “Finish” per completare l’operazione di aggiunta sorgente dati. Ora nella finestra “Data Sources” del report (Visualizzabile dal menu Data –> Show data Sources) avremo la sorgente reportDataDTO con l’elenco dei campi pubblici disponibili ed utilizzabili nel report. Non ci resta altro che “creare” graficamente il report aggiungendo con il semplice trascinamento i campi disponibili nell’area di lavoro dell’editor. Ecco il mio risultato:

rdlc_final

La parte di puro “design” è giunta al termine, ora dobbiamo iniziare a sporcarci un po’ le mani con del buon codice C#.

Per prima cosa ritocchiamo leggermente le impostazioni di compilazione del file rdlc all’interno del progetto Visual Studio. Per default i file rdlc vengono “inglobati” nell’eseguibile/libreria come risorse di progetto, mentre in molti casi è preferibile a mio parere lasciare il template esterno (e caricarlo “al volo” per la generazione del report) in modo da permettere correzioni o semplici modifiche estetiche al template senza la necessità di dover ricompilare e ridistribuire l’intero binario dell’applicazione. Per farlo dobbiamo selezionare il file rdlc nel ”Solution Explorer” di VS2008 e modificare alcune proprietà dalla apposita toolbox “Properties”; in particolare bisogna cambiare la proprietà “Build Action” dal default “Embedded Resource” in “None”. Inoltre impostiamo anche la proprietà “Copy to Output Directory” al valore “Copy if newer” in modo da fare una copia del file nella cartella dei binari ad ogni compilazione. Ecco le modifiche finali delle proprietà del file rdlc:

rdlc_prop
Ora siamo pronti per la generazione del report. Nell’applicazione del progetto di esempio aggiungiamo un bottone e nel gestore dell’evento “Click” di quest’ultimo iniziamo le operazioni per la generazione del PDF.

Per prima cosa simuliamo il caricamento dei dati da una ipotetica sorgente dati implementando un metodo che restituisca una lista di oggetti DTO, nel nostro caso sarà in realtà solamente uno. Il codice è banale e non fa altro che creare un’istanza della classe DTO, valorizzarne le proprietà (i dati utilizzati nell’esempio tra l’altro sono di un libro che vi consiglio di leggere Open-mouthed) e restituuirlo:

   1: private ReportDataDTO[] estraiDati()
   2: {
   3:     byte[] rawImg;
   4:     using (System.Drawing.Image img = System.Drawing.Bitmap.FromFile("RocketSurgeryCover.jpg"))
   5:     {
   6:         using (MemoryStream ms = new MemoryStream())
   7:         {
   8:             img.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);
   9:             rawImg = ms.ToArray();
  10:         }
  11:     }
  12:  
  13:     ReportDataDTO dto = new ReportDataDTO
  14:     {
  15:         IdArticolo = 9847,
  16:         Descrizione = "Rocket Surgery Made Easy: The Do-It-Yourself Guide to Finding and Fixing Usability Problems",
  17:         Dettagli = "It's been known for years that usability testing can dramatically...",
  18:         Costo = 21.99,
  19:         Immagine = rawImg
  20:     };
  21:     
  22:     return new ReportDataDTO[] { dto };
  23: }

Ora si passa alla generazione vera e proprio utilizzando la classe LocalReport che permette di elaborare un report rdlc ed effettuarne la renderizzazione. I passi da seguire sono il caricamento del file rdlc esterno impostando la proprietà “ReportPath”, aggiunta della sorgente dati da utilizzare, esecuzione del render specificando i parametri per generare un file in formato PDF ed infine il salvataggio dei dati risultanti dall’operazione precedente su file system, ed il gioco è fatto.

Il codice seguente (metodo “generaReport” richiamato dal gestore d’evento del bottone) implementa esattamente i passi appena descritti:

   1: private void generaReport()
   2: {
   3:     // Simulazione estrazione dati da una qualsiasi sorgente
   4:     ReportDataDTO[] dtoList = estraiDati();
   5:  
   6:     // Creazione istanza LocalReport e caricamento template rdlc e dati
   7:     LocalReport lr = new LocalReport();
   8:     lr.ReportPath = "ReportDemo.rdlc";
   9:     lr.DataSources.Add(new ReportDataSource("DemoReportPDF_ReportDataDTO", dtoList));
  10:  
  11:     // Elaborazione e render del report in formato PDF
  12:     Warning[] warnings;
  13:     string[] streamids;
  14:     string mimeType, encoding, extension;
  15:     string deviceInfo = "<DeviceInfo>" +
  16:                         "  <OutputFormat>PDF</OutputFormat>" +
  17:                         "</DeviceInfo>";
  18:  
  19:     byte[] bytes = lr.Render("PDF", deviceInfo, out mimeType, out encoding, out extension, out streamids, out warnings);
  20:  
  21:     // Salvataggio del report generato su file system
  22:     string reportFileName = Guid.NewGuid().ToString() + ".pdf";
  23:     using (MemoryStream ms = new MemoryStream(bytes))
  24:     {
  25:         using (FileStream fs = new FileStream(reportFileName, FileMode.Create))
  26:         {
  27:             fs.Write(bytes, 0, bytes.Length);
  28:             fs.Close();
  29:         }
  30:     }
  31:  
  32:     MessageBox.Show("Report generato correttamente: " + reportFileName);
  33: }

Le uniche due note da sottolineare sono:

- Nella fase di aggiunta dei dati deve essere specificato il nome con cui la sorgente dati è configurata all’interno dell’rdlc. Questo valore è presente (e modificabile) andando nel designer del report ed accedendo dal menu “Report” alla finestra “Report Data Sources”.

- La classe LocalReport fa parte del ridistribuibile Microsoft Report Viewer (installato da Visual Studio). Per poter ridistribuire l’applicazione in un PC con il solo framework .Net installato c’è bisogno anche di questo pacchetto scaricabile gratuitamente dal sito MSDN (il download si riferisce alla versione relativa al framework 3.5 SP1). Per l’utilizzo nel progetto è necessario aggiungere un riferimento all’assembly “Microsoft.ReportViewer.WinForms”.

E con questo è tutto, non resta che eseguire l’applicazione, premere il pulsante e se tutto è andato come dovrebbe, nella cartella di esecuzione del progetto dovrebbe comparire per incanto un file PDF più o meno così

pdf_result

 

File allegati:


Currently rated 5.0 by 2 people

  • Currently 5/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Innovactive Multi Sensor per Windows 7 Sensor API

February 16, 2010 13:33 by L.Maiorfi

Sulla scia del fermento intorno alla nuova runtime per l’interfacciamento con dispositivi a sensore introdotta in Windows 7, abbiamo realizzato un dispositivo “end-to-end” che permette al sistema operativo di utilizzare un accelerometro a 3 assi (l’ADXL-330, reso famoso dai controller della Wii, che ne hanno accelerato, senza giochi di parole, la diffusione) come periferica di tipo “sensore”, come illustrato nell’immagine che segue, in cui è mostrato il dispositivo all’interno del Device Manager di Windows:

image

Chi ha già dato un’occhiata alle Sensor API, avrà notato che Microsoft ha già classificato in categorie i sensori previsti (di movimento, biometrici, elettrici, ecc.) e per molti di essi è stato già fatto un tentativo di standardizzazione in termini di struttura dei dati esposti. Nel realizzare il nostro dispositivo ci siamo pertanto attenuti a tale categorizzazione, con l’intento di far funzionare il tutto senza toccare neanche una riga del client realizzato per l’hardware “ufficiale” che ha accompagnato già dalle prime dimostrazioni la SensorAPI di Windows 7, ossia la scheda della Freescale, con l’indubbio valore aggiunto però di funzionare in maniera completamente wireless!

Tale compatibilità “binaria”, oltre a richiedere che il dispositivo sia “decorato” dagli appositi metadati, ha imposto anche uno “shaping” dei dati ben preciso, attraverso l’inclusione all’interno di un contenitore (denominato “report”) in verità di per se’ molto poco tipizzato. Nel caso del nostro dispositivo, ad esempio, un sensore di movimento a tre assi ha richiesto che il report fosse costituito da un Dictionary contenente una coppia chiave-valore in cui la chiave fosse rappresentata da un ben preciso guid ed il valore da una lista di tre valori decimali (relativi alle componenti dell’accelerazione misurata in ciascuno dei tre assi).

Oltre alla realizzazione “fisica” della scheda, il dispositivo ha richiesto ovviamente la realizzazione di un apposito driver, in questo caso rappresentato da una dll (il driver in questione è infatti un UMDF e non un driver kernel, appoggiandosi in gran parte ad un’infrastruttura basata su architettura COM) compilata tramite il compilatore C++ contenuto nel WinDDK, l’SDK che Microsoft mette a disposizione per lo sviluppo di device driver. Il driver in questione (la scrittura del quale ha rappresentato effettivamente la parte più “rognosa” dello sviluppo del prototipo) viene installato in Windows 7 mediante un tool (devcon.exe) che, per tramite di un altro componente di supporto (il cosiddetto “CoInstaller”) ed un file .inf (analogo a quello di una qualsiasi altro device driver), registra effettivamente il nuovo dispositivo nel sistema.

Una volta registrato, il dispositivo diventa quindi disponibile per tutte le applicazioni, indipendentemente dal fatto che questo ad esempio utilizzi “risorse” tipicamente ad uso esclusivo da parte di un solo processo (come una porta seriale, ad esempio). Nel Pannello di Controllo il dispositivo viene reso effettivamente visibile attraverso la spunta del checkbox di attivazione, come illustrato nell’immagine seguente:

image

Lo screenshot sottostante mostra più istanze dello stesso client (puramente diagnostico, in questo caso) collegate alla medesima fonte dati costituita dal dispositivo in questione. L’interfaccia del client mostra sinteticamente l’accelerazione misurata su ciascuno degli assi (come riferimento, ogni “tick” rappresenta circa 0.5 G di accelerazione):

IAEMultiSensor

Il dispositivo (prototipale) ospiterà presto altri sensori (il che spiega il nome, dopo tutto), ma per il momento si presenta così:

IAEMultiSensor2_small

A questo punto non ci rimane che trovare un utilizzo plausibile per un dispositivo potenzialmente in grado di comunicare ad esempio la propria inclinazione al nostro PC a 1.6 km di distanza…un cucchiaione da paiolo remotizzato che dall’interno dell’auto ci permette di girare la polenta sui fornelli durante tutto il tragitto tra ufficio e casa?


Currently rated 4.5 by 2 people

  • Currently 4.5/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Applicazioni .NET MicroFramework? il MicroGardener!

February 2, 2010 13:06 by g.ruta

Chi ha partecipato all’evento DotNetUmbria che Innovactive ha organizzato lo scorso 15 Gennaio ricorda che una delle applicazioni più complete che abbiamo presentato (.NET MicroFramework ‘onboard’) consiste in una serra domestica il cui microclima può essere impostato a distanza, controllando parametri quali la temperatura, la luminosità e l’umidità del terreno.
In questi giorni abbiamo continuato a lavorare sul nostro prototipo portandolo a rappresentare, a nostro avviso, un sistema completo di monitoraggio remoto della serra; con questo post pertanto, a vantaggio di tutti, presentiamo schematicamente e illustriamo la soluzione completa, lo stato dell’arte del nostro MicroGardener.

MicroGardenerSchema

Come potete osservare nello schema sopra riportato la serra è dotata di sensori per rilevare costantemente il grado di umidità del terreno, la temperatura in prossimità delle piante e la luminosità ambientale. Tali dati vengono trasmessi wireless ad un modulo Tahoe (una scheda di sviluppo, tra le prime sul mercato che ci ha consentito di programmare e sperimentare con il MicroFramework) grazie ad una coppia di moduli XBee. Molto ci sarebbe da dire su questi dispositivi, ma allo scopo del nostro post basta dire che utilizziamo la ‘API Mode’ per configurare il modulo posto presso la serra come dispositivo che autonomamente trasmette i dati letti dai sensori e occasionalmente riceve un comando di attivazione/disattivazione di un attuatore, mentre il modulo posto presso la scheda di sviluppo Tahoe è in grado, grazie alla libreria Micro Framework Toolkit (http://mftoolkit.codeplex.com/) di interpretare lo stack XBee per le due situazioni di ricezione dei dati dei sensori e di invio dei comandi di attuazione.
Il dispositivo che abbiamo presentato nell’ambito del citato evento si fermava appunto al modulo Tahoe, che è dotato di un display LCD e di una serie di tasti per l’interazione con l’utente; il programma MicroFramework realizzato consente di leggere i valori che giungono dai sensori, visualizzarne graficamente l’andamento nel tempo e agire con i comandi sui singoli attuatori (una lampada per la luminosità, una lampada ad infrarossi per la temperatura e la pompa per l’irrigazione del terreno) oppure selezionando una modalità automatica, nella quale il software provvede al mantenimento dei parametri entro i range impostati per il microclima voluto, azionando in totale autonomia gli attuatori.
Un sistema come quello fin qui presentato, ovviamente, si limita a remotizzare il controllo della serra su distanze compatibili con la portata dei moduli XBee e può essere pensato comunque per l’applicazione domestica (o di vivaio) comunque locale. Come rendere il tutto veramente delocalizzato? Utilizzando il web, ovviamente!
Ecco in quale direzione abbiamo esteso il sistema: utilizzando come server web un modulo aggiuntivo ethernet per il Tahoe (prodotto, come il Tahoe, da Device Solutions; oggi nel loro catalogo si trova il modulo Tahoe-II, che già implementa funzionalità ethernet) abbiamo implementato una API REST che espone quanto ci serve per interagire con la serra in termini di lettura dati e impartizione dei comandi; un servizio WCF si occupa di interrogare periodicamente (polling) il server web per tenersi in memoria i dati dei sensori aggiornati; a questo punto sul web abbiamo pensato la possibilità per l’utente di poter controllare la serra con un semplice browser e, per rendere il tutto un po’ più accattivante, un client Silverlight.
I vantaggi di questa architettura sono molteplici in termini di scalabilità e di prestazioni: infatti pensando al servizio in rete locale con il modulo Tahoe l’attività di polling non viene effettuata su web; poi il tutto può essere implementato per più serre, ovvero per molti sistemi serra + XBee + Modulo MicroFramework; in fase di configurazione del servizio WCF impostiamo quali serre gestire (essenzialmente quali indirizzi interrogare con chiamate REST) e, all’atto di chiamata del servizio da parte di un client, il servizio fornirà all’utente la lista delle serre controllate per operare una scelta.
Completa il tutto un sottosistema che renderà felici gli scettici da una parte (se non vedo non credo!) e coloro che comunque vogliono gustarsi anche ‘a vista’ le loro piante o fiori: abbiamo munito la serra di webcam e instradato il segnale proveniente da essa tramite Microsoft Expression Encoder, esponendolo in streaming su server apposito; il client silverlight è stato munito dell’apposito controllo per la fruizione del flusso video in streaming e…
…eccovi il risultato finale!

MicroGardenerClient

Per vedere il sistema funzionante (con la sola avvertenza che attualmente la pompa per l’irrigazione è sostituita da una semplice lampadina per motivi di sicurezza) e provare ‘live’ a controllare la nostra piccola serra collegatevi alla dashboard di test, quindi selezionate ‘Innovactive Garden’ e cliccate su ‘Connect’…
…solo per utenti con il ‘pollice verde’!


Currently rated 5.0 by 2 people

  • Currently 5/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Develop Reality 2010 – Feedback dei partecipanti

January 18, 2010 12:14 by L.Maiorfi

Dopo una ‘onerosa’ elaborazione statistica eccovi tre grafici che sintetizzano i pareri che i partecipanti hanno dato in merito a vari aspetti dell’evento.
Ogni parere richiesto doveva essere espresso su una scala da 0 a 5; per ogni aspetto abbiamo riportato il valore medio su tutti i questionari compilati e il valore della deviazione standard dal valore medio. Noi stiamo già facendo le nostre considerazioni, e voi?

 GraficoEvento

GraficoEsperimenti

GraficoApplications


Currently rated 5.0 by 2 people

  • Currently 5/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Develop Reality 2010 – Debriefing e qualche foto…

January 17, 2010 12:44 by L.Maiorfi

Iniziando con un doveroso ringraziamento a tutti i partecipanti e a tutti coloro che hanno reso possibile questo evento, pubblico qualche foto a beneficio di chi non c'era (perdonato solo se impossibilitato a venire da cause di forza molto maggiore) e con l'occasione cerco di sintetizzare quelle che secondo la mia personale percezione sono le impressioni emerse intorno a questa iniziativa:

  • I nostri timori di essere i soli sulla terra cui interessi l'argomento dello sviluppo di software .NET che interagisca con il mondo reale sono svaniti
  • Il fermento dei partecipanti si è effettivamente diviso tra chi è più affascinato dalla possibilità di realizzare software per PC che interagisca con il mondo esterno e chi invece è più attratto dallo sviluppo di software .NET finalizzato ad essere eseguito direttamente su dispositivi embedded (tramite .NET MicroFramework)
  • Il feedback che abbiamo ricevuto ci ha dimostrato che in molti pensano come noi che studiare le metodologie e le tecnologie relative allo sviluppo di un'applicazione embedded (pura o ibrida che sia) aiuti ad essere degli sviluppatori migliori e dei professionisti più completi
  • La robotica piace più della domotica (anche se probabilmente in assoluto la prima fatturerà un milionesimo della seconda)
  • Il cruscottone WPF che mostrava in real-time i dati provenienti dai sensori è piaciuto probabilmente più della mini-serra automatica remotizzata programmabile con .NET, nonostante quest'ultima abbia richiesto almeno il decuplo in termini di ore/uomo
  • La maggioranza dei partecipanti avrebbe voluto vedere probabilmente più codice ed è per questo che spero che i nostri prossimi post tecnici di "dissecting" di quanto visto all'evento siano letti, commentati e, perché no, diventino lo spunto per proporre soluzioni, progetti ed iniziative che alimentino la passione dei membri della community su questi temi

Basta chiacchiere, ecco alcune foto:

Una sala immensa per dei dispositivi piccolissimi Lorenzo e Gianluca farfugliano insidiati dal trombettista alle loro spalle

 Hello LED in action! No, non è il tavolo del coffee break...è quello delle demo!


Currently rated 5.0 by 2 people

  • Currently 5/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Develop Reality 2010, prende forma la realtà

January 7, 2010 12:21 by L.Maiorfi

Come già anticipato con qualche immagine da Fabrizio qualche giorno fa, i preparativi per i "giocattoli hardware" da mostrare al Develop Reality 2010 in programma la settimana prossima.

Ecco qualche altro scatto di quello che (tempo permettendo) vedremo venerdì 15 come esempi di possibili realizzazioni:

camera_car2 001 camera_car 005

livorno 005 linefollowing 007

IMG_0201 IMG_0202

Non resta che venire per vedere tutto il resto :D

Ecco il link diretto alla pagina per la registrazione!


Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Logging delle eccezioni con ELMAH, un’introduzione

December 15, 2009 18:04 by M.Poponi

C'è solo una cosa di cui siamo sicuri quando scriviamo un qualunque software: prima o poi accadrà un'eccezione.
Accadrà perchè il software senza bachi non esiste, o perché la bella ma imprevedibile sistemista ha spento il DB, o solo perché l'utente ne sa una più del diavolo.
Gestire le eccezioni a volte non basta, o semplicemente ci è sfuggito quel caso, quel try, quell'inezia che dalla pancia del nostro programma rimbalza direttamente in faccia all'utente. Con la temuta paginona di errore di ASP.NET.
E' necessario quindi, specialmente in ambito web, avere una strategia un po' più sofisticata della semplice pagina di errore di .NET per la gestione o, almeno, per la rendicontazione e la registrazione di quanto è successo. Per capire dove, a chi e possibilmente, perché.
In questo post introdurremi i primi rudimenti dell'utilizzo di un tool open source, ELMAH, che ha come scopo proprio questo: fornire un framework semplice, potente e versatile per il logging e l'archiviazione delle eccezioni generate da un software ASP.NET.
In breve, le features principali di ELMAH sono
-logging automatico delle eccezioni non gestite
-logging delle eccezioni segnalate
-filtraggio delle eccezioni loggate
-utilizzo non intrusivo: basta aggiungere le dll di supporto, modificare il web config della nostra applicazione, e il gioco è fatto
-logging su diversi media: in RAM, su SQL server, Oracle, Acess, sql lite, XML...
-notifiche email degli errori
-report automatico: una pagina web permette di vedere la lista degli errori, i dettagli e persino la pagina errore originale.
-feed RSS degli errori, post su twitter (!) delle eccezioni

Per illustrare l'uso di questo semplice quanto potentissimo componente la cosa migliore è installarlo ed usarlo passo passo. Allegato a questo post trovate il semplice progetto ASP.NET 3.5 che andremo a costruire. Potete scaricare il progetto cliccando qui.

 

1) creiamo una semplice applicazione Web.


l'applicazione avrà una pagina con tre buttons e un link. 
Il primo bottone creerà un'eccezione di index out of bounds, non gestita. Questo è un errore tipico che magari può sfuggirci e, per i motivi più vari, non essere gestito e "finire" in faccia all'utente.

Il secondo istanzierà una classe contenuta in una class library, tenterà l'accesso ad un db utilizzando una stringa di configurazione errata, con eccezione non gestita. Anche in questo caso vedremo come l'eccezione verrà salvata.
Il terzo bottone tenterà anch'esso l'accesso al db, ma l'eccezione verrà gestita. Vedremo come registrare comunque in elmah l'avvenuto problema.

il semplice codice che realizza questi errori è il seguente

   1: protected void Button1_Click(object sender, EventArgs e)
   2:       {
   3:           int[] arr = new int[2];
   4:           arr[0] = 1;
   5:           arr[2] = 100;       
   6:  
   7:       }
   8:       protected void Button2_Click(object sender, EventArgs e)
   9:       {
  10:           liberia lib = new liberia();
  11:           lib.Accedi();
  12:  
  13:  
  14:       }
  15:  
  16:       protected void Button3_Click(object sender, EventArgs e)
  17:       {
  18:           try
  19:           {
  20:               liberia lib = new liberia();
  21:               lib.Accedi();
  22:           }
  23:           catch (ApplicationException ex)
  24:           {
  25:               Response.Write("si è verificata un'eccezione nell'accesso al db");
  26:               Elmah.ErrorSignal.FromCurrentContext().Raise(ex);  
  27:           }
  28:       }


Il link punterà ad una pagina inesistente, per vedere come vengono gestiti anche errori non direttamente generati dal codice.

Eseguendo l’applicazione e cliccando sul primo bottone, ci troveremo davanti alla normale pagina di errore di ASP.NET:

errore1

per prima cosa, ancora prima di installare ELMAH, per evitare che l'utente veda la pagina standard di errore, possiamo creare una nostra pagina in cui comunichiamo che si è verificata una eccezione, error.htm, e impostarla nel web.config come pagina di destinazione in caso di eccezione non gestita, utilizzando il seguente codice:

   1: <customErrors mode="On" defaultRedirect="error.htm">
   2: </customErrors>


per maggiori info sul tag customErrors si può vedere qui http://msdn.microsoft.com/en-us/library/h0hfz6fc.aspx

2) Installiamo  Elmah
Per iniziare dobbiamo scaricare l'ultima versione disponibile di ELMAH, facendo attenzione all'ambiente di destinazione, se è a 64 o 32 bit.
Troviamo la distribuzione qui:  http://code.google.com/p/elmah/

Nella distribuzione troviamo molti files. Un demo standalone che permette di testare le potenzialità di ELMAH e alcune cartelle con dentro i binari. Prendiamo i binari contenuti in bin\net-3.5\Release

e copiamoli nella directory \bin della nostra applicazione.

Aggiungiamo le references agli assembly elmah.dll e sqllite.

3) configuriamo ELMAH e cominciamo a loggare…

A questo punto, per utilizzare ELMAH basta configurare opportunamente il web.config.

Nel file di distribuzione è presente un file di configurazione generico, da cui possiamo “rubare” la configurazione del nostro web.config.

Nel nostro caso scegliamo di salvare gli errori generati su file XML. Questa è una situazione comoda per poter avere gli errori in un formato gestibile a posteriori. Se è possibile possiamo anche pensare di utilizzare SQLlite, o addirittura sql server. Quest’ultima opzione è sicuramente più potente e versatile, ma chiediamoci: se l’eccezione è proprio l’impossibilità di accedere al SQL Server, dove andrà a finire l’eccezione? :)

Come in ogni situazione, scegliamo fra le varie possibilità a disposizione quella che più si confà al problema che stiamo studiando. La potenza di ELMAH si vede anche dal fatto che possiamo cambiare idea in ogni momento, semplicemente riscrivendo il file di configurazione.

Pochi passi ci portano ad avere ELMAH funzionante:

aggiungiamo la sectionGroup nelle configSections

   1: <configuration>
   2:   <configSections> 
   3:     <sectionGroup name="elmah">
   4:           <section name="security" requirePermission="false" type="Elmah.SecuritySectionHandler, Elmah" />
   5:           <section name="errorLog" requirePermission="false" type="Elmah.ErrorLogSectionHandler, Elmah" />
   6:         </sectionGroup>

 

aggiungiamo la vera e propria sezione di configurazione, in cui diciamo ad ELMAH di loggare su file XML, nella cartella virtuale /logs della nostra applicazione (ovviamente avremo già creato tale cartella):

 

   1: <elmah>
   2:     <!-- errorLog type="Elmah.SQLiteErrorLog, Elmah" connectionStringName="ELMAH.SQLite" /-->
   3:      
   4:     <errorLog type="Elmah.XmlFileErrorLog, Elmah" logPath="~/logs" />
   5:   </elmah>

 

aggiungiamo ELMAH agli httphandlers e modules. Segnatamente, nel codice che segue, l’ultima riga degli handlers e le ultime due dei modules:

   1: <httpHandlers>
   2:   <remove verb="*" path="*.asmx" />
   3:   <add verb="*" path="*.asmx" validate="false" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
   4:   <add verb="*" path="*_AppService.axd" validate="false" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
   5:   <add verb="GET,HEAD" path="ScriptResource.axd" type="System.Web.Handlers.ScriptResourceHandler, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" validate="false" />
   6:   <add verb="POST,GET,HEAD" path="public/elmah.axd" type="Elmah.ErrorLogPageFactory, Elmah" />
   7: </httpHandlers>
   8: <httpModules>
   9:   <add name="ScriptModule" type="System.Web.Handlers.ScriptModule, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
  10:   <add name="ErrorLog" type="Elmah.ErrorLogModule, Elmah" />
  11:   <add name="ErrorFilter" type="Elmah.ErrorFilterModule, Elmah" />
  12:  
  13: </httpModules>

in particolare nella riga

   1: <add verb="POST,GET,HEAD" path="public/elmah.axd" type="Elmah.ErrorLogPageFactory, Elmah" />

 

diciamo che la pagina in cui vogliamo vedere i report di errore generati sarà la pagina \public\elmah.axd.

Questo se vogliamo poter accedere da non autenticati ad una cartella che in questo caso abbiamo chiamato \public\ che è liberamente accessibile. Chiaramente sarebbe meglio che questa cartella avesse un nome meno ovvio… L’utilità è quella di poter accedere remotamente al report degli errori anche quando l’errore si verifica proprio nel controllo degli utenti.

Dovremmo quindi, se scegliamo di percorrere questa strada, creare una cartella \Public settando opportunamente le politiche di controllo degli accessi. Non dobbiamo creare alcun file particolare al suo interno, segnatamente non è necessario creare elmah.axd.

4) Fatto. Sentito niente?

A questo punto abbiamo la nostra applicazione che logga ogni errore. L’utente finale vedrà solo l’educatissima pagina error.htm, in cui ci scusiamo dell’errore avvenuto. Ovviamente potremmo anche utilizzare una pagina aspx che riprende una eventuale MasterPage, per rendere l’esperienza ancora più indolore.

Se premiamo i bottoni e clicchiamo sul link, sbirciando nella directory \logs vedremo 4 files:

   1: 15/12/2009  17.02            12.789 error-2009-12-15160210Z-f82885d7-74eb-41c8-bc54-e4d72639f51c.xml
   2: 15/12/2009  17.03            15.605 error-2009-12-15160300Z-fa4ecb0c-2d4f-4f85-9a56-f7672cf4bc5e.xml
   3: 15/12/2009  17.03            15.601 error-2009-12-15160305Z-1fe0f86d-454b-4cc4-a357-1fb4bc4aa1a1.xml
   4: 15/12/2009  17.03             7.247 error-2009-12-15160324Z-13e498bf-87c2-4fce-8af9-e10fc312de81.xml

 

che sono i quattro files xml contenenti tutti i dati degli errori avvenuti.

navigando invece sulla pagina \public\elmah.axd avremo un report interattivo degli errori avvenuti:

report

la cosa interessante è che oltre all’ora, all’utente e al tipo di errore, cliccando su details si hanno tutte le informazioni di contesto e di debug che possiamo sperare di avere, dallo stack completo dell’errore a tutte informazioni di contesto http, dal viewstate completo per arrivare perfino alla pagina di errore originale.

conclusioni

Questo post non dà che un assaggio delle potenzialità di ELMAH. Soprattutto la possibilità di innestare in un’applicazione già esistente, senza alcun cambiamento invasivo al codice, di un framework potente e utilissimo per il logging degli errori.

Una volta capito come utilizzare ELMAH e apprezzata la potenza e la facilità d’uso, si potrà approfondirne lo studio e utilizzarne le funzioni più approfonditamente, per esempio leggendo questo articolo: http://code.google.com/p/elmah/wiki/DotNetSlackersArticle.

Buon lavoro e come sempre buon divertimento.


Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

incremento automatico della versione in Visual Studio

December 10, 2009 17:42 by M.Poponi

 

C'è un tool che ho cominciato ad usare e di cui non riesco più a fare a meno. La necessità che avevo era quella di avere in maniera automatica, ma controllata, l'incremento del versioning dei miei progetti, sia web, che library che winforms.
Ho scoperto per caso questo add-in per visual studio:
http://team.sfi.vn/post/Build-Version-Increment-Add-In-Visual-Studio.aspx

una volta installato, riavviando visual studio avremo un nuovo item nel menu Tools:

menu

questo comando aprirà una finestra moltro scarna, nel cui albero di sinistra troveremo la nostra solution e i nostri progetti, e nel pannello di destra le varie opzioni per il progetto scelto:

finestra

 

Le opzioni più importanti sono quelle del Versioning Style. Per ognuna delle cifre della versione possiamo scegliere fra una nutrita lista di opzioni, da None, che non cambia il numero (per esempio la major  generalmente è legata a stadi di rilascio, più che di build) a cifre come il giorno dell’anno, il mese, o un semplice incremento.

Si può specificare quale versione incrementare, o se l’incremento avviene al build, al rebuild o sempre.

una possibile configurazione, per esempio è la seguente:

dettaglio

una volta impostato, il tool provvederà automaticamente a modificare (con preventivo checkout se necessario) il file assemblyinfo.cs, come per esempio nel codice che segue:

// Version information for an assembly consists of the following four values:
//
//      Major Version
//      Minor Version
//      Build Number
//      Revision
//
// You can specify all the values or you can default the Revision and Build Numbers
// by using the '*' as shown below:
[assembly: AssemblyVersion("1.9344.10.2")]
[assembly: AssemblyFileVersion("1.9344.10.2")]

a questo punto avremo in maniera automatica e flessibile incrementato ad ogni build la versione del nostro progetto.

semplice, efficace ed utile.


Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Visual Studio 2010 – Prime impressioni sulla Beta 2

October 28, 2009 16:28 by L.Maiorfi

Come sicuramente oramai avrete appreso dai numerosissimi blog e siti web che ne hanno dato notizia, nelle scorse settimane è stato reso disponibile il download di una nuova versione beta dell’ambiente di sviluppo di riferimento su piattaforma Microsoft.

Il nuovo aggiornamento di Visual Studio farà parte di un salto generazionale di gran lunga più consistente di quanto è avvenuto con il rilascio della versione 2008, in quanto per la prima volta da 5 anni a questa parte assisteremo alla pubblicazione di una nuova runtime (la versione 3.5 del Framework utilizza infatti i componenti “core” di .NET 2.0), denominata con ammirevole fantasia .NET 4.0.

Sono moltissime le novità introdotte, letteralmente a 360 gradi, da Microsoft con questa nuova “sessione” di rilasci che avrà luogo molto probabilmente nel mese di Marzo 2010, ed è quindi molto difficile orientarsi nel tentativo di distinguere quello che effettivamente cambierà il modo di sviluppare applicazioni per chi fa questo come attività professionale rispetto alle novità che invece dimenticheremo dopo i primi minuti di utilizzo (qualcuno si ricorda dell’eco data dalle prime recensioni di Visual Studio 2005 alla funzionalità che evidenziava in giallo e verde le righe modificate o aggiunte ad un sorgente tra un salvataggio ed il successivo?).

Ad ogni modo, da qualche parte bisognava pure iniziare e noi abbiamo installato il nuovo Visual Studio all’interno di una macchina virtuale VirtualBox con sistema operativo Windows 7 Starter Edition (il tutto all’interno di una macchina fisica Vista 64 con 4Gb di ram).

Le prime impressioni, che vogliamo condividere attraverso qualche screenshot, non possono non tenere conto della completa riscrittura dell’IDE, che ora utilizza WPF, che ora vanta un’interfaccia utente molto più ricca ma, a dire il vero, anche sensibilmente più lenta, anche se su questo punto converrà esprimersi solo una volta valutata la versione definitiva e in un ambiente non virtualizzato.

Il primo screenshot si riferisce ad una panoramica dell’editor testuale (C# e XAML nell’esempio riportato) che grazie alla versione di WPF contenuta in .NET 4 raggiunge dei livelli di leggibilità del testo su LCD veramente notevoli, anche a dimensioni relativamente piccole (8 e inferiori).

Editor

Nella seconda immagine abbiamo riportato una piccola testimonianza di quello che crediamo migliorerà la vita di chi come noi spende molte ore del proprio tempo facendo debugging (non perché il software scritto sia buggato, sia ben chiaro…), ossia la possibilità di “ancorare” un quickwatch alla riga contenente l’espressione sotto controllo, come il contenuto di textbox1.Text ed il parametro “e” nell’esempio sotto (notate il piccolo pushpin nel tooltip/quickwatch).

Quickwatch pinned

Da non trascurare poi la nuova suite di designer per la modellazione, in grado di produrre diagrammi UML quali Sequence, Class Diagram, grafi di dipendenza tra classi, namespace, assembly e molto altro.

3

Sono state integrate inoltre le funzionalità di editing T-SQL di SQL Server Management Studio 2008, come illustrato nell’immagine seguente:

4

Ultimo ma non ultimo, non è da trascurare che ogni nuova release di Visual Studio accorpa di fatto tutte le estensioni (o almeno quelle ufficiali) rilasciate successivamente all’ambiente di sviluppo, quali ad es. ASP.NET MVC e ASP.NET MVC 2, Silverlight 3, Azure SDK, ecc.

La lista dei template di progetto built-in è infatti molto nutrita:

Template progetti


Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

EQATEC Tracer e Profiler

September 16, 2009 11:48 by l.maiorfi

Quante volte ci è capitato di rimpiangere di non aver debitamente “instrumentato” un’applicazione per far sì che fossero loggate le chiamate ai vari metodi (ed i relativi parametri) nel momento in cui si presenta un problema in produzione?

Lo scenario tipico è rappresentato dalla telefonata del cliente che vi dice “ho fatto questa cosa e l’applicazione si è bloccata e l’ho dovuta chiudere da Task Manager”, oppure “ho cliccato sul tasto stampa ma il programma non ha fatto niente”, oppure ancora “per l’operazione che fino a ieri mi ci metteva pochi secondi oggi il programma mi fa aspettare qualche minuto”, e così via…

Bene, oggi abbiamo testato due prodotti free della EQATEC (http://www.eqatec.com/) che saranno di grande aiuto per risolvere le situazioni di cui sopra.

Il Tracer consente di “instrumentare” un insieme di assembly .NET contenuti (necessariamente) nella cartella specificata (con tanto di drag&drop), di cui verrà creata una copia allo scopo. Verrà quindi popolato un treeview con la struttura degli assembly e dei metodi singolarmente tracciabili. Ad ogni esecuzione di uno dei metodi selezionati il tracer visualizzerà il nome del metodo chiamato ed il valore dei parametri in ingresso (solo per i tipi base, però).

Notevole, veramente.

EQATEC Tracer

Il Profiler funziona in maneira analoga, ma traccia anche le durate della chiamata di ciascun metodo, oltre a diverse altre informazioni utili.

Alcune di osservazioni:

  • il tracing e/o il profiling può avvenire addirittura via rete TCP/IP, permettendovi di fare diagnostica sulla macchina del cliente rimanendo comodamente seduti dietro la vostra scrivania (VPN permettendo)
  • i tool della EQATEC sono realizzati come applicazioni WPF
  • in fase di compilazione, l’approccio migliore per l’instrumentazione automatica del proprio codice resta a nostro avviso PostSharp + Laos

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5