Archive

Archive for the ‘Programmazione’ Category

Jun
28

Molto spesso, durante l’attività di programmazione, ci si trova a lavorare con un tipo di dato che può creare non pochi problemi: le date.

Fin quando abbiamo a che fare con date astratte (date storiche) o stiamo realizzando applicazioni che opereranno sempre all’interno di una Time Zone, il problema può anche non porsi e il classico tipo “DateTime” assolve egregiamente il suo compito.

Di recente tuttavia mi sono trovato a lavorare su un progetto per la realizzazione di un’applicazione distribuita in cui gli utenti:

  • accedono da time zone differenti;
  • manipolano dati che possono riferirsi a varie Time Zone.

In questo caso si presenta il problema non solo dei fusi orari ma anche del Daylight Saving che non tutte le time zone osservano. Il classico “DateTime” di conseguenza, memorizzando solamente l’ora locale, non è più in grado di fornirmi tutte le informazioni di cui ho bisogno e non mi permette di dedurre né in che fuso orario mi trovo e né se mi trovo in Daylight Saving Time.

La soluzione arriva da un nuovo tipo di dato, introdotto nel framework 3.5, che memorizza il tempo in formato UTC (Coordinated Universal Time) anziché come “Local Time”: DateTimeOffset.

worldzones

Il DateTimeOffset descrive il tempo al meridiano di Greenwith e non è influenzato dal Daylight Saving. Il local time viene memorizzato come una coppia di valori: il primo valore è l’ora UTC mentre il secondo è l’offset tra UTC e il local time.

Ad esempio le ore 3:15 in un fuso UTC + 1 verranno memorizzate come 4:15 + 01:00 mentre in un fuso orario UTC + 2 come 5:15 + 02:00. Questi due valori, sebbene indichino la stessa ora locale, descrivono 2 punti diversi nel tempo e possono facilmente essere distinte l’una dall’altra. Questo ci permette di gestire correttamente anche le transizioni di tempo legate al Daylight Saving.

In definitiva il tipo DateTime è utilizzabile per:

  • rappresentare solo valori di date (non di tempo);
  • rappresentare solo valori di tempo (non di date);
  • Lavorare con date astratte (date storiche);
  • Lavorare con DataBase o API che non supportano il tipo DateTimeOffset.

Viceversa, il DateTimeOffset va usato per:

  • Identificare univocamente un punto nel tempo;
  • Registrare degli eventi che si verificano in un determinato momento;
  • Eseguire operazioni aritmetiche con date e ore;
  • Lavorare con i fusi orari;
  • Lavorare con i Daylight Saving Times.

Per info dettagliate sull’utilizzo del tipo DateTimeOffset è possibile consultare il seguente link ufficiale.

, , , , ,

Jul
29

ADO.NET offre un supporto nativo per i dati disconnessi attraverso oggetti come DataAdpter, Dataset e DataTable. Se da un lato però tali strumenti presentano il vantaggio di permettere l’accesso ai dati in modo disconnesso, dall’altro possono risultare poco performanti (e a volte addirittura inutilizzabili) quando ad esempio si ha necessità di leggere una grande quantità di dati.

 

E’ proprio questo il problema che abbiamo dovuto affrontare durante lo sviluppo di un modulo sw che fosse in grado di caricare ed elaborare un elevato numero di record da un Database SQL Server (parliamo di circa 5.000.000 di record ad elaborazione). L’utilizzo di oggetti come i DataAdapter e DataSet portava inevitabilmente ad una eccezzione di “OutOfMemory”.

 

In questi casi è dunque consigliabile effettuare un accesso sequenziale ai dati e ciò è possibile tramite l’oggetto DataReader di ADO.NET.

I risultati vengono restituiti all’esecuzione della query e vengono archiviati nel buffer di rete del client finché non vengono richiesti utilizzando il metodo Read del DataReader. L’utilizzo del DataReader consente di migliorare le prestazioni dell’applicazione recuperando i dati non appena sono disponibili e, per impostazione predefinita, archiviando solo una riga alla volta per evitare di sovraccaricare il sistema.

 

Per recuperare dati mediante un DataReader, è necessario creare un’istanza dell’oggetto Command, quindi creare un DataReader chiamando Command.ExecuteReader per recuperare righe da un’origine dati.

Il metodo Read dell’oggetto DataReader viene utilizzato per ottenere una riga dai risultati della query. È possibile accedere a ogni colonna della riga restituita passando il nome o il riferimento ordinale della colonna al DataReader. Per migliorare le prestazioni, tuttavia, DataReader fornisce una serie di metodi che consentono di accedere ai valori delle colonne nei tipi di dati nativi, quali GetDateTime, GetDouble, GetGuid, GetInt32 e così via.

 

Di seguito un esempio di utilizzo dei DataReader:


SqlCommand command = new SqlCommand(
  "SELECT CategoryID, CategoryName FROM dbo.Categories;" +
  "SELECT EmployeeID, LastName FROM dbo.Employees", connection);
connection.Open();
SqlDataReader reader = command.ExecuteReader();
do
{
  Console.WriteLine("\t{0}\t{1}", reader.GetName(0), reader.GetName(1));
  while (reader.Read())
    Console.WriteLine("\t{0}\t{1}", reader.GetInt32(0), reader.GetString(1));
} while (reader.NextResult());
reader.Close();
connection.Close();

È necessario chiamare sempre il metodo Close una volta terminato l’utilizzo dell’oggetto DataReader.

I parametri di output o i valori restituiti presenti nell’oggetto Command non saranno disponibili fino a quando l’oggetto DataReader non viene chiuso.

Notare che quando è aperto un oggetto DataReader, l’oggetto Connection viene utilizzato esclusivamente da quell’oggetto DataReader. Non sarà possibile eseguire alcun comando per l’oggetto Connection, né creare un altro DataReader fino a quando il DataReader originale non viene chiuso.

 

Per altre info su Metodi e Proprietà dell’oggetto vi rimandiamo alla documentazione ufficiale del Framework.

 

May
31

Chi ha mai sentito parlare di DevExpress (Developer Express)?
Come suggerisce il nome stesso, DevExpress sono un insieme di tools e controlli che si integrano perfettamente con Microsoft Visual Studio e che rendono più “veloce” lo sviluppo di applicazioni .NET.
Di incredibile valore aggiunto alla programmazione sono infatti tutti i controlli del pacchetto (che comprendono controlli Windows Form, ASP NET, Silverlight, WPF) ma soprattutto un plug-in, CodeRush, di grande aiuto alla scrittura del codice.
Ed è proprio alla descrizione di questi ultimi componenti che voglio dedicare il mio post di oggi in quanto utilizzati con successo e grande soddisfazione nelle ultime applicazioni Windows Form sviluppate da MAS Consulting.

Esempio graficoParlando dei controlli la cosa che salta immediatamente all’occhio è la personalizzazione grafica che permettono di fare. Ad ogni controllo è infatti possibile assegnare uno style di visualizzazione rendendo l’applicazione molto più accattivante dal punto di vista grafico.
A questo aspetto puramente visivo si affianca il ben più importante aspetto funzionale. L’insieme di controlli ha infatti tutta una serie di funzionalità che altrimenti dovrebbero essere sviluppate manualmente dal programmatore con dispendio di tempo e risorse.
GridControlUn tipico esempio è rappresentato dai controlli “DataGrid” & “Data Editing”. Come si può vedere dall’immagine, questi controlli permettono tutta usa serie di operazioni di Business Intelligence (Grouping, Filtering, Summary ecc…) del tutto assenti nei comuni controlli Windows. Ciò permette all’utilizzatore finale di crearsi, con il minimo sforzo, delle rappresentazioni personalizzate dei propri dati.
Ne risulta una più efficiente e veloce attività di programmazione ma soprattutto una migliore esperienza di usabilità dell’applicazione da parte del cliente.

Ad Escusivo vantaggio dell’attività di programmazione è invece il plug-in CodeRush.
CodeRush è un plug-in di Visual Studio .NET che permette di creare e mantenere il codice sorgente con estrema efficienza.

Le sue principali caratteristiche sono:

  • Consume-first Development: Scrivere il codice e poi dichiarare istantaneamente i pezzi mancanticonsume-first_development
  • Strumenti di selezione avanzati: espandere o comprimere selezioni di blocchi logici, inglobare porzioni di codici in blocchi try/finally o try/catch
  • Generazione automatica di codice: Creazione di blocchi di codice comuni istantaneamente con i modelli presenti, che forniscono delle scorciatoie efficienti e facili da usare per la scrittura di codice. I modelli possono aumentare la produttività di codifica fino al 300%.  E per le squadre, i modelli possono aiutare a mantenere codice coerente tra tutti gli sviluppatori.CodeProviders
  • Analisi del codice in Background: Errori, avvertimenti e suggerimenti sono segnalati in tempo reale mentre si lavora. 

Tutte queste caratteristiche e molte altre fanno di DevExpress uno strumento a mio parere indispenzabile nella programmazione .NET sia in termini di efficienza di sviluppo che in termini di soddisfazione del cliente nonchè dell’utilizzatore finale dell’applicazione.

Mar
30

Uno degli argomenti di maggiore interesse in un’applicazione, sia essa Web o Enterprise, è sicuramente quello della Sicurezza.

La sicurezza in quanto tale deve essere pensata a tutti i livelli:

  • a livello architetturale: la sicurezza va pensata globalmente. L’applicazione deve essere in grado di difendersi dagli attacchi che il nostro sistema può portarle e deve sapere che attacchi possono arrivare;
  • a livello di codice: ogni singola parte del nostro codice deve partire dal presupposto che i controlli di sicurezza fatti ad un altro livello possano fallire, possano non esserci o possano essere sbagliati;
  • a livello sociologico: l’ultimo ostacolo alla vera sicurezza resta l’impatto che la nostra applicazione avrà sull’utilizzatore finale, quali passi quest’ultimo dovrà intraprendere per far si che la sicurezza venga rispettata e mantenuta. Se i passi e gli sforzi che l’utente dovrà fare sono o troppo difficili o comportano tempi di attesa decisamente non accettabili, allora significa che abbiamo fallito, la sicurezza non verrà rispettata e le falle che si creeranno nella nostra applicazione rischieranno di diventare falle per l’intero sistema ospite, compromettendo, la sicurezza dell’intera infrastruttura;
  • a livello amministrativo: la sicurezza ha un costo anche in termini di manutenzione nel tempo, pensiamo solo al tempo che un amministratore di rete dedica a mantenere aggiornata la struttura di Active Directory che ha in gestione, se l’infrastruttura di sicurezza introdotta dalla nostra applicazione ha un costo di gestione elevato rischiamo che alla lunga venga trascurata perchè troppo onerosa.

Se focalizziamo l’attenzione sugli ultimi due punti ci rendiamo conto che uno dei fattori fondamentali è quello di cercare di rendere la sicurezza il più integrata possibile con il sistema ospite, cercare di renderla il più trasparente possibile a tutti, sia agli amministratori che dovranno gestirla e ancora di più agli utenti finali che dovranno “subirla” come imposizione.

In questa direzione una possibile soluzione è il concetto di “Single Sign On”.

Si parla di sistema basato su “Single Sign On” (SSO) quando le richieste di autenticazione non vengono direttamente gestite dal sistema stesso ma vengono ridirette verso un’altro sistema di autenticazione che ha precedentemente certificato le credenziali dell’utente connesso, senza quindi avere la necessità di richiedere nuovamente le credenziali per l’accesso.

L’obiettivo principe del Single Sign On è proprio quello di rendere la sicurezza trasparente all’utente finale, facilmente manutenibile e gestibile per gli amministratori; l’utente deve rendersi conto di lavorare in un sistema sicuro, ma non deve assolutamente vivere la sicurezza come un onere aggiuntivo.

Una possibile scelta in questo senso è quella di integrare un sistema di “Single Sign On” all’interno delle nostre applicazioni appoggiandoci semplicemente alla gestione degli utenti e gruppi di Windows. In questo modo il nostro sistema si integrerà perfettamente anche con “Active Directory” (con tutti i pregi e difetti del caso che prescindono però dalla trattazione di questo post e che verranno trattati in successivi post).

 

L’architettura

 

Schema DB SSOAbbiamo una tabella “Users” dedicata a contenere i dati relativi agli utenti, una tabella “Roles” che conterrà l’elenco dei ruoli e infine una tabella “RolesRelations” che è dedicata a mantenere le relazioni molti a molti tra gli utenti e i ruoli e, nel caso specifico, tra i ruoli e i ruoli stessi permettendoci di gestire quindi l’inserimento di un ruolo all’interno di un altro ruolo semplificando, in questo modo, di molto la manutenzione nel tempo delle policy di sicurezza dell’applicazione stessa.

Un campo chiave nella base dati è, nella tabella “Users”, il campo “AccountSID”, che  è dedicato a contenere il SID (Security Identifier) dell’utente di Windows o di Active Directory che desideriamo possa accedere alla nostra applicazione. La tabella però non contiene solo un riferimento al SID dell’utente perché è strutturata per permetterci di inserire anche utenti personalizzati che non appartengono al dominio e permetterci quindi di far accedere all’applicazione anche utenti e/o macchine che non fanno direttamente parte della nostra struttura di Active Directory.

 

L’applicazione all’avvio esegue i seguenti passi:

  • recupera il SID dell’utente corrente di Windows, quello cioè della macchina locale su cui è in esecuzione;
  • verifica se il SID, così recuperato, sia presente nella tabella “Users” della nostra base dati:
    • in caso affermativo: Costruisce una GenericIdentity e un GenericPrincipal con le informazioni presenti nella tabella “Users”, assegnando al GenericPrincipal i ruoli corretti sulla base delle relazioni impostate nella tabella “RolesRelations”. Infine assegna il GenericPrincipal ottenuto alla proprietà statica CurrentPrincipal della classe Thread.
    • In caso negativo: Ci limitiamo a mostrare all’utente una bella maschera di richiesta di credenziali e procediamo allo stesso modo, verifichiamo cioè se le credenziali immesse dall’utente, che sappiamo non appartenere al dominio o non essere tra quelli abilitati al “Single Sign On”, siano corrette e in caso affermativo procediamo creando una GenericIdentity e un GenericPrincipal. La verifica viene fatta sempre a fronte dei dati contenuti nella tabella “Users” ma questa volta confrontando la combinazione di Username e Password immessi dall’utente.

Al termine del processo di autenticazione dell’utente sia che il sistema di “Single Sign On” sia entrato in funzione sia che l’utente sia stato autenticato con un processo custom otteniamo lo stesso effetto, abbiamo cioè un GenericPrincipal assegnato al thread corrente e questo ci garantisce che il motore che gestisce la sicurezza all’interno del .NET Framework funzioni come ci aspettiamo.

 

fonti: MSDN Library

 

, ,

Nov
15

SQL Server Reporting Services fornisce un intervallo completo di strumenti e servizi pronti all’uso che consentono di creare, distribuire e gestire report.

ms159106.4441bf97-fdda-468a-9163-8ee9ea1739bd(it-it,SQL.105)Reporting Services è una piattaforma basata su server che fornisce funzionalità complete per la gestione di report per diversi tipi di origini dati. Reporting Services include un set completo di strumenti per la creazione, la gestione e il recapito di report e contiene API che consentono agli sviluppatori di integrare o estendere l’elaborazione di dati e report in applicazioni personalizzate. Gli strumenti di Reporting Services operano in ambiente Microsoft Visual Studio e sono completamente integrati con gli strumenti e i componenti di SQL Server.

SSRS consente quindi di creare report interattivi, tabella, grafico o in formato libero dalle origini dei dati relazionali, multidimensionali o basate su XML, nonché pubblicare report, pianificarne l’elaborazione o accedere ai report su richiesta. Reporting Services consente inoltre di creare report ad hoc in base a modelli predefiniti e di esplorare i dati contenuti nel modello in modo interattivo. È possibile visualizzare i report in numerosi formati diversi, esportarli in altre applicazioni e sottoscrivere report pubblicati. I report creati possono essere visualizzati tramite una connessione Web o come parte di un’applicazione Microsoft Windows o di un sito di SharePoint. Reporting Services fornisce la chiave per accedere ai dati aziendali.

Per chi si occupa di Business Intelligence, le novità principali che arrivano con la versione di SQL server 2008 sono proprio i Reporting Services, con miglioramenti su vari fronti.

Per quanto riguarda l’aspetto architetturale, la novità principale consiste nella rimozione del vincolo per cui SSRS doveva essere installato sulla stessa macchina in cui era presente Internet Information Server. La nuova versione utilizza le HTTP Server API di HTTP.SYS e ASP.NET per sostituire IIS, ed ha consolidato in un unico servizio le funzionalità prima suddivise fra ReportServer, Gestione report e l’elaborazione e il recapito automatico in background.

Sul fronte del rendering, la maggiore novità è data dalla possibilità di esportare in Microsoft Word i report prodotti, forse la funzionalità maggiormente richiesta dagli utenti; anche l’esportazione in formato Excel e CSV  è stata migliorata.

Nell’ambito della creazione dei report le principali novità sono:

  • il supporto più completo ai grafici, con l’introduzione di nuovi tipi di grafici – a cilindro, a piramide, a imbuto, polare, radar, azionario, a candela, istogramma a intervalli, ad area smussata, a linee smussate, a linee con rientri e BoxPlot – e maggiori possibilità di controllo su etichette, allineamento, colori e serie, grazie all’utilizzo dei componenti sviluppati da Dundas Data Visualization, recentemente acquisiti da Microsoft;
  • la nuova area dati Tablix: è un nuovo elemento dati, che consentono di realizzare molto più velocemente report tabellari complessi, ad esempio report di conto economico che presentano totalizzazioni a diversi livelli che devono essere gestite a report. Funzionano bene e riducono drasticamente i tempi di realizzazione;
  • le nuove funzionalità per testo e HTML, che consentono di modificare l’aspetto di singole porzioni di testo all’interno delle caselle di testo ed importare codice HTML da un campo del database per visualizzarlo nel report;

Se dopo aver letto le caratteristiche della nuova versione di SQL Server Reporting Services si volesse iniziare ad utilizzarlo, è utile ricordare che non è necessario effettuare l’upgrade anche del database: è possibile installare SSRS 2008 continuando ad adoperare come sorgente dati la versione di SQL Server 2000 o 2005 attualmente in uso.

, , ,