web dev comments edit

Nel periodo pre-ferie, ho dedicato un po’ del mio tempo libero a studiare un po’ le novità che ci circonderanno da qui a breve e, da buon blogger (non è molto vero in quest’ultimo periodo), ne sono nati tre articoli che riporto qui di seguito:

 

Il mio preferito rimane sicuramente quello sui Web Worker e File API, anche se devo dire che il porting di IE9 su Mango mi ha davvero impressionato Smile

Buon lettura

various comments edit

Recentemente sono stato contattato per due posizioni aperte come Web Developer in zona Milano, se qualcuno di voi è interessato mi può contattare liberamente da qui.

web dev comments edit

Oggi ho avuto la necessità di analizzare del traffico di rete la cui Request partiva dalla mia macchina, per poi finire verso un webserver Java hostato in https su di un webserver Apache. Essendo esposto in BasicHttpBinding, il suo utilizzo è risultato da subito molto semplice; un semplice AddServiceReference da VisualStudio e poche righe di codice per cominciare a comunicare con la piattaforma esterna.

Tale comunicazione è avvenuta senza problemi al primo colpo, ma il dato restituito non conteneva tutte le informazioni che mi sarei aspettato per quella chiamata. Purtroppo dall’altra parte mi son sentito dire che il problema risiedeva nei miei proxy e che il parser dell’xml restituito dal servizio era errato.

Fortunatamente non ho mai avuto problemi di questo tipo con i proxy creati tramite svcutil, quindi mi sono messo ad analizzare i pacchetti di rete tra la mia macchina ed i servizi in questione. Durante tale analisi ho riscontrato due problemi:

  1. Il traffico di rete tra la mia macchina ed i servizi avveniva tramite una connessione sicura https;
  2. Le chiamate venivano effettuate tramite un’applicazione web che non viene tracciata di default tramite fiddler;

Entrambi i punti sono facilmente risolvibili. Per la parte https è necessario installare l’ultima versione di Fiddler (scaricabile da qui) ed attivare la relativa opzione nei suoi setting, come mostrato dagli screenshots seguenti:

SNAGHTML7ba8f5bSNAGHTML7bb638b

Maggiori info riguardo Fiddler e https sono disponibili qui.

Per quanto riguarda invece il problema di monitorare il traffico in uscita da un’applicazione web, è sufficiente cambiare l’identity dell’application pool con cui viene eseguital’applicazione ed impostare lo stesso utente con cui gira Fiddler (quindi l’utente loggato). A questo punto come per magia verrà mostrato anche il traffico della vostra web application.
La “vicenda” si è conclusa dimostrando che i servizi non restituivano le informazioni aspettate Smile

asp.net comments edit

In un post precedente (vedi qui) ho già introdotto il concetto di ActionFilter e alcune opportunità che ci offre. In questo post vorrei mostrare come realizzarne uno custom per loggare le eccezioni.
Per prima cosa è bene sapere che ogni ActionFilter deve ereditare da FilterAttribute, che è la classe base per tutti i Filter che si utilizzano in ASPNET MVC e, se si vogliono catturare tutti gli errori non gestiti, è necessario implementare anche l’interfaccia IExceptionFilter.

Lo snippet seguente mostra l’implementazione dell’ActionFilter:

public class LoggerFilterAttribute : FilterAttribute, IExceptionFilter {
    readonly ILogger logger;

    /// <summary>
    /// Initializes a new instance of the <see cref="T:System.Web.Mvc.FilterAttribute"/> class.
    /// </summary>
    public LoggerFilterAttribute ( ) {
        logger = new Logger()
    }

    /// <summary>
    /// Initializes a new instance of the <see cref="T:System.Web.Mvc.FilterAttribute"/> class.
    /// </summary>
    public LoggerFilterAttribute ( ILogger logger ) {
        this.logger = logger;
    }

    /// <summary>
    /// Called when an exception occurs.
    /// </summary>
    /// <param name="context">The filter context.</param>
    public void OnException ( ExceptionContext context ) {
        logger.Error ( context.Exception.Message, context.Exception );

        throw new HttpException(500,context.Exception.Message,context.Exception);
    }
}

A questo punto è sufficiente decorare i nostri Controller, o ancora meglio registrare il Filter come Global per poterlo sfruttare:

[LoggerFilterAttribute()]
public class HomeController : ControllerBase {
  public ActionResunt Index(){
    //DO SOMETHING
  }
}

Ciauz

orm comments edit

Tra le varie problematiche che ho incontrato nello sviluppare Dexter, ce n’è una il cui rimedio è divenuto indispensabile nella maggior parte delle applicazioni, ossia una gestione un po’ più avanzata del DateTime all’interno dell’applicazione.
Durante la migrazione tra i vari server, ho riscontrato un problema con i vari DateTime di ciascuno di essi; essendo dislocati in aree geografiche diverse, restituivano infatti valori nettamente differenti per via del fuso orario dal server vecchio a quello nuovo.

Il primo server su cui risiedeva il mio blog era su un provider il cui fuso orario era impostato su EST, che differisce di tre ore rispetto all’orario del nuovo server che è impostato sulla PST. Questa differenza ha causato un’errata visualizzazione degli orari dei post sul mio blog, che risultavano sfalzati di tre ore

Oltre a sistemare tutti i valori memorizzati nel database con una query, ho deciso di affrontare e risolvere il problema in modo da non avere una dipendenza del fuso orario nelle date memorizzate, essendo quindi libero di gestire l’output dell’ora nel TimeZone a me più congeniale.

Per prima cosa ho realizzato uno UserType per NHibernate che convertisse tutte le date in ingresso verso il databse in formato UTC e, in fase di idratazione della entity, le convertisse nel TimeZone da me configurato. Questa operazione, in codice, si traduce più o meno così:

[Serializable]
internal class DateTimeUtc : IUserType {
    #region IUserType Members

    /// <summary>
    /// Determines whether the specified <see cref="System.Object"/> is equal to this instance.
    /// </summary>
    /// <param name="x">The <see cref="System.Object"/> to compare with this instance.</param>
    /// <param name="y">The y.</param>
    /// <returns>
    ///     <c>true</c> if the specified <see cref="System.Object"/> is equal to this instance; otherwise, <c>false</c>.
    /// </returns>
    public new bool Equals ( object x , object y ) {
        if ( ReferenceEquals ( x , y ) ) {
            return true;
        }
        if ( x == null || y == null ) {
            return false;
        }
        return x.Equals ( y );
    }

    /// <summary>
    /// Returns a hash code for this instance.
    /// </summary>
    /// <param name="x">The x.</param>
    /// <returns>
    /// A hash code for this instance, suitable for use in hashing algorithms and data structures like a hash table. 
    /// </returns>
    public int GetHashCode ( object x ) {
        return x == null
                   ? typeof ( DateTime ).GetHashCode ( ) + 473
                   : x.GetHashCode ( );
    }

    /// <summary>
    /// Retrieve an instance of the mapped class from a JDBC resultset.
    /// Implementors should handle possibility of null values.
    /// </summary>
    /// <param name="rs">a IDataReader</param>
    /// <param name="names">column names</param>
    /// <param name="owner">the containing entity</param>
    /// <returns></returns>
    /// <exception cref="T:NHibernate.HibernateException">HibernateException</exception>
    public object NullSafeGet ( IDataReader rs , string[] names , object owner ) {
        object obj = NHibernateUtil.DateTime.NullSafeGet ( rs , names[ 0 ] );
        if ( obj == null ) {
            return null;
        }

        var dbValue = ( DateTime ) obj;

        SiteConfiguration configuration = DexterContainer.Resolve <IConfigurationRepository> ( ).Configuration;

        dbValue = configuration != null
                      ? System.TimeZoneInfo.ConvertTimeFromUtc ( dbValue , configuration.TimeZone )
                      : dbValue.ToUniversalTime ( );

        return dbValue;
    }

    /// <summary>
    /// Write an instance of the mapped class to a prepared statement.
    /// Implementors should handle possibility of null values.
    /// A multi-column type should be written to parameters starting from index.
    /// </summary>
    /// <param name="cmd">a IDbCommand</param>
    /// <param name="value">the object to write</param>
    /// <param name="index">command parameter index</param>
    /// <exception cref="T:NHibernate.HibernateException">HibernateException</exception>
    public void NullSafeSet ( IDbCommand cmd , object value , int index ) {
        if ( value == null ) {
            ( ( IDataParameter ) cmd.Parameters[ index ] ).Value = DBNull.Value;
        }
        else {
            var myValue = ( DateTime ) value;

            SiteConfiguration configuration = DexterContainer.Resolve<IConfigurationRepository> ( ).Configuration;

            if ( configuration != null ) {
                myValue = myValue.Kind == DateTimeKind.Unspecified
                              ? System.TimeZoneInfo.ConvertTimeToUtc ( myValue , configuration.TimeZone )
                              : myValue.ToUniversalTime ( );
            }
            else {
                myValue.ToUniversalTime ( );
            }

            ( ( IDataParameter ) cmd.Parameters[ index ] ).Value = myValue;
        }
    }

    /// <summary>
    /// Return a deep copy of the persistent state, stopping at entities and at collections.
    /// </summary>
    /// <param name="value">generally a collection element or entity field</param>
    /// <returns>a copy</returns>
    public object DeepCopy ( object value ) {
        return value;
    }

    /// <summary>
    /// During merge, replace the existing (<paramref name="target"/>) value in the entity
    /// we are merging to with a new (<paramref name="original"/>) value from the detached
    /// entity we are merging. For immutable objects, or null values, it is safe to simply
    /// return the first parameter. For mutable objects, it is safe to return a copy of the
    /// first parameter. For objects with component values, it might make sense to
    /// recursively replace component values.
    /// </summary>
    /// <param name="original">the value from the detached entity being merged</param>
    /// <param name="target">the value in the managed entity</param>
    /// <param name="owner">the managed entity</param>
    /// <returns>the value to be merged</returns>
    public object Replace ( object original , object target , object owner ) {
        return original;
    }

    /// <summary>
    /// Reconstruct an object from the cacheable representation. At the very least this
    /// method should perform a deep copy if the type is mutable. (optional operation)
    /// </summary>
    /// <param name="cached">the object to be cached</param>
    /// <param name="owner">the owner of the cached object</param>
    /// <returns>
    /// a reconstructed object from the cachable representation
    /// </returns>
    public object Assemble ( object cached , object owner ) {
        return cached;
    }

    /// <summary>
    /// Transform the object into its cacheable representation. At the very least this
    /// method should perform a deep copy if the type is mutable. That may not be enough
    /// for some implementations, however; for example, associations must be cached as
    /// identifier values. (optional operation)
    /// </summary>
    /// <param name="value">the object to be cached</param>
    /// <returns>a cacheable representation of the object</returns>
    public object Disassemble ( object value ) {
        return value;
    }

    /// <summary>
    /// The SQL types for the columns mapped by this type.
    /// </summary>
    /// <value></value>
    public SqlType[] SqlTypes {
        get {
            return new[] {
                new SqlType ( DbType.DateTime )
            };
        }
    }

    /// <summary>
    /// The type returned by <c>NullSafeGet()</c>
    /// </summary>
    /// <value></value>
    public Type ReturnedType {
        get { return typeof ( DateTime ); }
    }

    /// <summary>
    /// Are objects of this type mutable?
    /// </summary>
    /// <value></value>
    public bool IsMutable {
        get { return false; }
    }

    #endregion
}

Una volta affrontato il problema del salvataggio della data, rimaneva soltanto quello riguardante i filtri delle query che, per i campi DateTime, dovevano effettuare una conversione in formato UTC più o meno in questo modo:

SNAGHTML2d258d7

Purtroppo mi è capitato più volte di dimenticarmi di effettuare quel ToUniversalDateTime all’assegnazione del parametro di una query, con l’ovvio problema di avere risultati sballati in fase di visualizzazione.

Fortunatamente con la versione 3.2 di NHibernate è stato rivisto parzialmente il Driver di SqlServer, che ora espone un metodo "AdjustCommand” subito prima dell’ExecuteQuery. Il codice seguente mostra come effettuare automaticamente la conversione dal DateTimeKind.Local al DateTimeKind.Utc:

public class DexterSqlClientDriver : SqlClientDriver {
    
    public override void AdjustCommand ( System.Data.IDbCommand command ) {
        foreach (var parameter in command.Parameters.Cast<SqlParameter> ( ).Where ( x => x.SqlDbType == SqlDbType.DateTime && ( x.Value is DateTime ) )) {
            var dateTimeValue = (( DateTime )parameter.Value).ToUniversalTime (  );
            parameter.Value = dateTimeValue;
        }
    }
}

A questo punto, il codice di esecuzione della query si semplifica ancor di più poiché il developer non deve sapere, o ricordarsi, che il formato della data sul database è differente, in quanto la conversione avviene in automatico.
Il risultato è il seguente:

SNAGHTML2d2e78f

Comodo no?

asp.net comments edit

Seguire tutte le tecnologie di cui siamo appassionati diventa sempre più difficile, e le quantità di informazioni presenti in rete a volte superano di gran lunga il tempo che si ha a disposizione per studiarle/lavorarci; se proviamo a seguire l’hashtag #html5 su twitter ci rendiamo conto che arrivano centinaia di tweet al minuto.
Proprio da queste problematiche ed esigenze è nata l’idea di creare dei post con cadenza più o meno regolare (l’idea è sul settimanale) che raccolgono i principali link per le tecnologie di cui sono appasionato.
Buona lettura Smile

Windows Azure:

HTML5:

ASPNET MVC:

Testing:

asp.net comments edit

Già dalla prima release di ASPNET MVC è stato introdotto il concetto di Action Filter, ossia un attributo che può decorare sia una singola Action o che addirittura un intero Controller.

Lo scopo di questi Filter è quello di aggiungere funzionalità che spesso ci troveremmo a scrivere con molta frequenza, o addirittura per ogni singola chiamata; per capire il concetto è sufficiente pensare ad una serie di Action che dovranno essere accessibili soltanto agli utenti loggati. Se provate ad immaginare questo scenario, un possibile risultato potrebbe essere questo:

public class HomeController : Controller {
    public ActionResult Index ( ) {
        if(!HttpContext.User.Identity.IsAuthenticated)
            Redirect ( "/Login" );

        //TODO: Fai qualcosa

        return View ( );
    }

    public ActionResult Products ( ) {
        if (!HttpContext.User.Identity.IsAuthenticated)
            Redirect ( "/Login" );

        //TODO: Fai qualcosa

        return View ( );
    }

    public ActionResult Details ( ) {
        if (!HttpContext.User.Identity.IsAuthenticated)
            Redirect ( "/Login" );

        //TODO: Fai qualcosa

        return View ( );
    }
}

Come si può notare in tutte e tre le Action c’è un blocco di codice ripetuto che non fa altro che verificare che l’utente corrente sia autenticato e, nel caso non lo sia, lo reindirizza alla pagina di Login. Lo scopo degli Action Filter è di racchiudere tutta la logica che può essere comune alle Action, indipendentemente dal Binder in entrata e da ciò che la Action stessa deve fare, permettendoci così di sostituire tutte quelle righe di codice con un semplice attributo. Di fatto l’esecuzione del Filter avviene prima dell’esecuzione del codice presente all’interno della Action.
Lo snippet seguente mostra le stesse identiche Action dell’esempio precedente, ma con l’utilizzo degli Action Filter:

public class HomeController : Controller {
    [Authorize]
    public ActionResult Index ( ) {
        //TODO: Fai qualcosa

        return View ( );
    }

    [Authorize]
    public ActionResult Products ( ) {
        //TODO: Fai qualcosa

        return View ( );
    }

    [Authorize]
    public ActionResult Details ( ) {
        //TODO: Fai qualcosa

        return View ( );
    }
}

Oppure a livello di controller

[Authorize]
public class HomeController : Controller {
    public ActionResult Index ( ) {
        //TODO: Fai qualcosa

        return View ( );
    }

    public ActionResult Products ( ) {
        //TODO: Fai qualcosa

        return View ( );
    }
    
    public ActionResult Details ( ) {
        //TODO: Fai qualcosa

        return View ( );
    }
}

All’interno di MVC esistono già diversi Action Filter, come l’Authorize mostrato sopra, oltre ad altri come OutputCache, HandleError, etc; inoltre nulla ci vieta di crearne dei nostri custom, come mostrato in un mio precedente post (qui).

L’ultima release di MVC (la 3, di cui ho già parlato in parte qui) offre la possibilità di registrare i controlli in modalità globale per tutta l’applicazione, evitandoci così il noioso copia ed incolla per tutti i controller dell’applicazione.

Per far ciò è necessario registrare l’Action Filter nel global.asax, come mostrato di seguito:

protected void Application_Start ( ) {
    AreaRegistration.RegisterAllAreas ( );

    GlobalFilters.Filters.Add ( new HandleErrorAttribute ( ) );
    GlobalFilters.Filters.Add ( new AuthorizeAttribute ( ) );

    RegisterRoutes ( RouteTable.Routes );
}

Non male direi.

Ciauz

asp.net comments edit

Sicuramente la parola NuGet, precedentemente conosciuto come NuPack, non è un termine nuovo per i tecnici; non avendo però mai avuto modo di parlarne colgo l’occasione per scrivere questo post, che riassume un po’ il suo funzionamento e ne spiega gli scenari d’uso.
In primis NuGet è un’extension free per Visual Studio 2010, quindi per chi non utilizza questa release di VS questo post può risultare poco utile. Lo scopo dell’extension è di agevolare lo sviluppatore nell’utilizzo di Framework esterni, principalmente Open Source all’interno dei propri progetti C# o VB.

Ogni mia solution utilizza diversi pacchetti come NHibernate, ConfORM, Castle, JQuery etc, e, specie in fase di startup, è necessario aggiungere queste librerie sia ad ogni progetto sia al source control;
NuGet facilita parecchio questa fase permettendoci con pochi click, di completare gli step descritti precedentemente, ma anche di aggiornare le librerie a versioni più recenti con estrema facilità.

Installazione:

Essendo questo tool sviluppato dal team di ASP.NET/MVC, l’istallazione è disponibile sia tramite gli ASP.NET MVC 3 Tools Update (download qui) che tramite la gallery delle extension di Visual Studio (qui). Se siete sviluppatori web consiglio l’installazione di NuGet insieme ad MVC, che include altre ottime features per il mondo “WWW”; se invece il vostro target di sviluppo non è il web, sicuramente l’installazione della singola extension è la soluzione migliore.

Utilizzo:

Una volta installato il tutto è possibile utilizzare NuGet in due differenti modi:

  • Riga di comando direttamente dentro Visual Studio (molt geek ma poco utile a mio avviso);
  • Tramite l’apposita UI.

Se si opta per la prima soluzione basta digitare all’interno della finestra “Package Manager Console” (disponibile dopo l’installazione di NuGet dal menu View => Other Windows) il comando “Install-Package”, seguito dal nome del package da installare. Supponendo di voler installare jquery, il codice da scrivere deve essere il suguente:

image

Se invece si opta per l’utilizzo tramite la UI di Visual Studio è sufficiente andare sul progetto desiderato e, cliccando con il tasto destro sulle reference, premere “Add Library Package Reference” e ricercare JQuery, come mostrato dagli screenshot seguenti:

SNAGHTML3ecbbb5cSNAGHTML3eccda80

SNAGHTML3ecedf9eSNAGHTML3effd3fb

Dipendenze:

Oltre al download della singola libreria, NuGet si occupa di fornire al nostro download anche le dipendenze del package scelto. Riferendosi ad un esempio pratico, se si prova a scaricare Castle Windsor verrà scaricato anche il package di Castle.Core, in quanto necessario al funzionamento del primo; il tutto risulterà come una duplice installazione di librerie tramite NuGet, ossia è come installare prima Castle.Core e poi Castle.Windsor. Lo screenshot seguente mostra la dipendenza:

SNAGHTML3f150ee9

FileSystem:

Ovviamente, tutti i package installati nelle nostre solution devono essere fruibili anche in assenza di connessione, e questo significa che esiste una copia in locale all’interno del proprio FileSystem. Il comportamento di default di NuGet è quello di copiare tutte le librerie all’interno della folder (packages) presente nella stessa folder della solution.
Purtroppo nella versione attuale di NuGet (la 1.3, e ricordiamoci che stiamo parlando di un “prodotto” in beta) non esiste ufficialmente la possibilità di specificare in che folder devono essere installati i package. Alcune settimane fa il buon Andrea ha postato un “trick” che permette di cambiare i settings di NuGet e poter gestire liberamente il path che conterrà le librerie. Come detto dal PM del progetto Phil Haack qui:

SNAGHTML3f06ea2a

Le prossime release saranno incompatibili con la soluzione descritta da Andrea. Speriamo di avere a disposizione una soluzione alternativa.

Gallery:

Ovviamente è già disponibile un gran numero di package che si possono utilizzare liberamente,  ed esiste un apposito sito che ci consente di consultare l’archivio e di lasciare dei feedback sulle varie librerie o di caricarne di nuove. Il sito in questione è http://www.nuget.org 

SNAGHTML3efc4016SNAGHTML3efc90d4

SNAGHTML3efd9bdcSNAGHTML3efcd1ab

Estendibilità:

NuGet è fortemente basato su feed xml per la consultazione dei package disponibili e, andando sui suoi setting, potete aggiungere feed custom per installazione di pacchetti “privati”, e quindi utilizzare questa potente extension anche per librerie non open source o non rilasciate pubblicamente.
Sul sito di Codeplex (http://nuget.codeplex.com) è disponibile un’ottima documentazione che, tra le tante info, spiega come creare ed “hostare” un proprio feed all’interno di Nuget (vedi qui).

Considerazioni:

Sinceramente rientra tra i “Must Have” e, una volta rotto il ghiaccio, è difficile farne a meno. Una cosa che sicuramente sarebbe carina è la possibilità di configurare i package per il singolo download. Per esempio è possibile utilizzare NHIbernate con diversi proxy (LingFu, Castle, etc.), e in NuGet trovate tanti pacchetti quante sono le opzioni. Sicuramente la possibilità di personalizzarsi il package può essere di aiuto nello “sfoltire” una gallery molto grande.

web dev comments edit

Internet Explorer, nonostante sia sempre stato uno dei browser più diffusi in ambiente Windows, non ha mai brillato per caratteristiche di sviluppo, a paragone con quelle offerte da Firefox con Firebug o Chrome con la sua developer toolbar.

Fortunatamente il team di Redmond si è dato da fare per cercare di colmare questa lacuna e, nell’ultima release, ha introdotto alcune feature che lo collocano al “pari” della concorrenza e, in alcuni scenari, anche leggermente avanti.

Banalmente se si preme F12 in IE9 si possono subito notare alcune voci precedentemente assenti, come il tab Network, che ci permette di effettuare un monitoring sulle richieste che partono dal client verso il server.
Sinceramente non volevo soffermarmi su questa feature o effettuare un paragone tra le varie toolbar, ma semplicemente mostrare una funzionalità molto comoda che in alcune situazioni può essere la nostra migliore amica Smile.

Sicuramente tutti i dev sono a conoscenza della “minifizzazione” dei file (normalmente file .js e .css) e, di fatto, jQuery e molte altre librerie offrono due versioni dei proprio framework: una normale ed una compressa.
Per ovvi motivi è sempre giusto utilizzare la seconda nei propri siti; questo ci permette di ridurre banda e, di conseguenza, i tempi di caricamento delle nostre pagine. Purtroppo di riflesso si ha anche lo svantaggio di perdere leggibilità e facilità di debugging dei javascript.
Internet Explorer 9 offre una fantastica funzione che ci consente di scavalcare questa problematica aiutandoci parecchio nella fase di sviluppo. Questa feature ci permette di “indentare” il codice javascript presente all’interno della toolbar, come mostrato dagli screenshot seguenti:

001002003