asp.net comments edit


GroudZeroEventBrite_thumb


Il 22 Luglio si terrà Ground Zero, ovvero il primo evento “di lancio” di DotNetLombardia: sarà un’intera giornata di approfondimento dedicata alle più recenti tecnologie, ed io avrò la fortuna di tenere una sessione riguardante il mondo web.

Sono molto felice di partecipare come speaker a questo evento, la cui agenda è sicuramente interessante; in più c’è il debutto del mio desk neighbor Matteo, che avrà modo di parlare del mondo mobile e di Windows Phone.

Direi che ora è tempo di preparare un po’ di materiale in quanto gli argomenti sono molti e tutti interessanti: come preannuncia il titolo di questo post mostrerò un cocktail delle novità riguardanti lo sviluppo web con il .NET Framework 4.0.

L’agenda è disponibile qui, mentre la registrazione qui.
Non mancate!

Ciauz

asp.net comments edit

Una delle cose che trovo più belle di Spark è la possibilità di ridurre, a volte anche dimezzare, il numero di righe di codice presenti all’interno delle nostre View.

Fortunatamente con MVC molta della logica non esiste più, a parte quella riguardante la visualizzazione o meno di un blocco di html, il cambiamento di un css in base ad una condizione, oppure l’iterazione di una collection; in soldoni non dovremmo avere molto codice all’interno se non delle if/else, dei for.

Supponiamo di avere un codice come il seguente:

<%if (Model.RecentPost.Count > 0){%>
<li>
   something
</li>
<%}%>

in Spark possiamo rimuovere due righe, la prima di apertura della if e quella di chiusura, impostando la condizione direttamente nell’attributo del tag da mostrare, come da snippet seguente:

<li if="Model.RecentPost.Count > 0">
    something
</li>

Ovviamente, se la if non deve racchiudere un solo tag ma più blocchi di tag non annidati, si può utilizzare l’apposita sintassi di Spark che, come potete vedere dall’esempio seguente, è molto simile al codice HTML:

<if confition="Model.RecentPost.Count > 0">
    <li>something</li>
    <li>something 1</li>
    <li>something 2</li>
</if>

Anche le altre condizioni else ed elseif funzionano allo stesso modo:

<li if="Model.RecentPost.Count > 0">something</li>
<li elseif="Model.RecentPost.Count == 0">something 1</li>
<else>
    <li>something 2</li>
</else>

Oppure:

<if condition="Model.RecentPost.Count > 0">
   <li>something</li>
</if>
<else if="Model.RecentPost.Count == 0">
  <li>something 2</li>
</else>
<else>
  <li>something 3</li>
</else>

Enjoy Spark

asp.net comments edit

Già nel post precedente ho introdotto SparkViewEngine; in questo voglio mostrare un’interessante feature che apre diversi scenari di mantenibilità e di “servizio”, come nel caso di Dexter che mostrerò più avanti.

Sicuramente ci sarà capitato molto spesso di dover “hostare” le nostre applicazioni all’interno di una virtual directory, e magari di doverle spostare successivamente sulla root di un sito e viceversa: spesso questo risulta scomodo in quanto può comportare alcune modifiche ai percorsi dei file di risorse (immagini, css, javascript, etc). Se proviamo a guardare il lato pratico, un codice html simile a questo:

<link type="text/css" rel="stylesheet" href="/Styles/Site.css" />

non sarebbe più valido nel caso il sito fosse spostato all’interno di una virtual directory, e dovrebbe diventare una cosa del tipo:

<link type="text/css" rel="stylesheet" href="/MyVirtualDirectory/Styles/Site.css" />

 

Ovviamente il problema è risolvibile sfruttando un helper che effettua il resolve dell’url, con il conseguente svantaggio di aggiungere codice all’interno del markup, rendendo difficile un eventuale refactoring; a questo si aggiunge la perdita in leggibilità del codice html. Un’altra soluzione è far gestire i percorsi delle risorse a Spark (devo dire che lo fa egregiamente e con estrema semplicità) : in primis è necessario modificare il web.config aggiungendo la sezione di Spark, come mostrato di seguito:

<section name="spark" type="Spark.Configuration.SparkSectionHandler, Spark" requirePermission="false"/>
</configSections>

<spark>
    <compilation debug="false"/>
    <pages automaticEncoding="true">
        <namespaces>
            <add namespace="System" />
            <add namespace="System.Web" />
            <add namespace="System.Web.Mvc" />
            <add namespace="System.Web.Mvc.Ajax" />
            <add namespace="System.Web.Mvc.Html" />
            <add namespace="System.Web.Routing" />
            <add namespace="System.Linq" />
        </namespaces>
        <resources>
            <add match="~/Scripts" location="/Resource/Scripts" />
            <add match="~/Styles" location="/Resource/Styles" />
            <add match="~/Images" location="/Resource/Images" />
            <add match="~/Media" location="/Resource/Media" />
        </resources>
    </pages>
</spark>

Come potete intuire la sezione resource è quella più interessante, e ci permette di specificare dove sono presenti i files delle risorse: quindi, lato view, è sufficiente utilizzare il tilde per indicare il percorso iniziale dell’applicativo, poi ci penserà spark in fase di rendering a sostituirlo con quanto specifica nel file di configurazione.
Se proviamo a renderizzare questo codice html con i settaggi sopra specificati, il rendering finale dovrebbe essere questo:

<link type="text/css" rel="stylesheet" href="~/Styles/Site.css" />

<link type="text/css" rel="stylesheet" href="/Resouce/Styles/Site.css" />

 

Ovviamente questo può aprire un ulteriore scenario, ossia offrire la possibilità a chi sviluppa la parte html di utilizzare alcune CDN (google, Microsoft, etc) senza doverne conoscere il percorso; di fatto, chi vuole sviluppare una skin per dexter e vuole utilizzare la cdn di Microsoft per jQuery, può semplicemente scrivere questo:

<script src="~/Scripts/CDN/jQueryTools/1.2.2/jquery.tools.min.js" type="text/javascript" language="javascript"></script>

Così facendo si può cambiare in un qualsiasi momento la CDN da utilzzare, o scegliere di hostare il file con la libreria su un proprio server.
Di seguito riporto il blocco di configurazione di spark in dexter, che mostra le varie CDN supportate:

<spark>
    <compilation debug="false"/>
    <pages automaticEncoding="true">
        <namespaces>
            <add namespace="System" />
            <add namespace="System.Web" />
            <add namespace="System.Web.Mvc" />
            <add namespace="System.Web.Mvc.Ajax" />
            <add namespace="System.Web.Mvc.Html" />
            <add namespace="System.Web.Routing" />
            <add namespace="System.Linq" />
            <add namespace="Dexter.Web.Site.Models.Blog" />
            <add namespace="System.Collections.Generic" />
            <add namespace="Dexter.Web.Mvc.Helpers" />
            <add namespace="Dexter.Core.Configuration" />
            <add namespace="Dexter.Core.Concrete" />
            <add namespace="Dexter.Web.Mvc.Controls" />
        </namespaces>
        <resources>
            <add match="~/Scripts/CDN/Microsoft" location="http://ajax.microsoft.com/ajax"/>                 <!-- http://www.asp.net/ajaxlibrary/cdn.ashx -->
            <add match="~/Scripts/CDN/Google" location="http://ajax.googleapis.com/ajax/libs"/>                 <!-- http://code.google.com/apis/ajaxlibs/documentation/#AjaxLibraries -->
            <add match="~/Scripts/CDN/jQueryTools" location="http://cdn.jquerytools.org"/>                    <!-- http://flowplayer.org/tools/download/index.html -->
            <add match="~/Scripts" location="~/Scripts" />
            <add match="~/Styles" location="~/Styles" />
            <add match="~/Images" location="~/Images" />
            <add match="~/Media" location="~/Media" />
        </resources>
    </pages>
</spark>

Ciauz

.net comments edit

Oggi mi è capitato un errore alquanto curioso che, se non si sta molto attenti, può portare via parecchio tempo; ma partiamo con ordine.

Il buon Mauro mi ha passato un set di librerie da utilizzare in un applicativo interno che avevo necessità di aggiornare, ed il trasferimento (per puri motivi di pigrizia) è avvenuto via messenger.  Ovviamente, senza pensarci su troppo, ho copiato le nuove librerie all’interno della bin in modo da aggiornare l’applicazione all’ultima versione ma, dopo il primo avvio, ricevevo la seguente eccezione:

Security Exception

Description: The application attempted to perform an operation not allowed by the security policy.  To grant this application the required permission please contact your system administrator or change the application's trust level in the configuration file.

Exception Details: System.Security.SecurityException: Request for the permission of type 'System.Web.AspNetHostingPermission, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' failed.

Source Error:

An unhandled exception was generated during the execution of the current web request. Information regarding the origin and location of the exception can be identified using the exception stack trace below.

Stack Trace:


[SecurityException: Request for the permission of type 'System.Web.AspNetHostingPermission, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' failed.]
   System.Reflection.Assembly._GetType(String name, Boolean throwOnError, Boolean ignoreCase) +0
   System.Reflection.Assembly.GetType(String name, Boolean throwOnError, Boolean ignoreCase) +42
   System.Web.UI.Util.GetTypeFromAssemblies(ICollection assemblies, String typeName, Boolean ignoreCase) +145
   System.Web.UI.TemplateParser.GetType(String typeName, Boolean ignoreCase, Boolean throwOnError) +73
   System.Web.UI.TemplateParser.ProcessInheritsAttribute(String baseTypeName, String codeFileBaseTypeName, String src, Assembly assembly) +111
   System.Web.UI.TemplateParser.PostProcessMainDirectiveAttributes(IDictionary parseData) +279

Il messaggio era alquanto preoccupante e, dopo vari check della configurazione (full trust mode, etc), ho trovato la soluzione nell’unblock del file; di fatto, essendo questi arrivati da una fonte non sicura, Windows ha giustamente pensato di impedirne l’utilizzo salvo previa autorizzazione dell’utente stesso, che può essere effettuata tramite la finestra delle proprietà, come da screenshot seguente:

SNAGHTML55018f8

asp.net comments edit

Ultimamente in Dexter stiamo aggiungendo una batteria di servizi per poter realizzare delle applicazioni client che possano interagire con il nostro engine e, nello specifico, applicazioni riguardanti il neonato Windows Phone 7, IPhone, IPad ed Android.
Testando il primo servizio sono incappato subito in un errore riguardante la raggiungibilità del servizio stesso, ricevendo da IIS un HTTP Error 404.3 - Not Found, nonostante che il servizio fosse presente e correttamente configurato.

Il problema era dovuto al fatto che nel mio IIS locale non erano registrati tutti i moduli necessari al funzionamento del servizio; tutto ciò è facilmente risolvibile eseguendo dal prompt del dos I seguenti comandi:

cd c:\windows\Microsoft.Net\Framework\v3.0\Windows Communication Foundation\

ServiceModelReg –i

A questo punto nella schermata dovrebbero apparire tutta una serie di messaggi che informano l’utente su cosa è stato installato.
Scopo del post è ricordarsi il comando Smile

Ciauz

various comments edit

Esame Designing & Developing Web Applications using Microsoft .NET Framewrok 4.0 passato!

image


Peccato non aver potuto dare l’altro Sad smile

asp.net comments edit

Già nel post precedente avevo annunciato una serie di contenuti riguardanti SparkViewEngine. Per approfondire l’utilizzo di questo engine ho cominciato il porting della skin del mio blog: devo dire che, man mano che lo utilizzo, rimango colpito dalla sua produttività e potenza, a partire dalle cose più semplici fino ad arrivare a funzioni un po’ più avanzate che permettono di creare delle vere e proprie funzioni e/o ottimizzazioni.

Per chi non abbia voglia di aspettare e voglia vedere un utilizzo un po’ più “spinto” di Spark, consiglio di dare un’occhiata al codice di Dexter e, nello specifico, alla cartella Themes/Fusion, dove si trova il porting della mia skin che è abbastanza ricca di html.

Come preannuncia il titolo, questo post ha lo scopo di mostrare come utilizzare da subito per una semplicissima applicazione SparkViewEngine, quindi configurarlo e capirne un po’ la logica.

Una volta scaricato il codice da qui, basta referenziare le due Assembly che ne permettono l’utilizzo in ASP.NET MVC, Spark.dll e Spark.Web.Mvc.Dll e registrare il nuovo ViewEngine allo startup dell’applicativo; quindi nel global.asax.cs basta inserire il seguente codice:

protected void Application_Start(object sender, EventArgs e)
{
    RegisterRoutes(RouteTable.Routes);
    SparkEngineStarter.RegisterViewEngine();
}

A questo punto l’applicazione è abile ed arruolata a sfruttare tutte le potenzialità di Spark, ma prima di scrivere un po’ di codice nella view è importante sapere che:

  • La struttura delle folder contenente le View è esattamente la stessa che si avrebbe senza spark.
  • Tutti I files delle view, partial view, master, etc devono avere estensione .spark;
  • All’interno della cartella shared normalmente va creato un file “_global.spark” contenente tutti i vari using ed eventuali macro necessari alla costruzione della vista;
  • La master page di default (anch’essa presente nella cartella shared) si chiama “Application.spark”;

A questo punto dovrebbe esser ben chiaro il fatto che abbiamo una cartella Views/Shared ed al suo interno abbiamo la nostra master page “Application.spark”; salvo forzature esplicite, tutte le viste erediteranno da questa master, e, se lo si vuole, resta comunque possibile specificare una master differente, ma lo vedremo più avanti.

Il codice seguente mostra una master page realizzata con spark:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
        <title><use content="title">${Model.Title}</use></title>
        <meta name="description" content="${Model.Description}" /> 
        <meta name="keywords" content="${Model.KeyWords}" /> 
        <meta name="author" content="${Model.Author}" />
        <link rel="SHORTCUT ICON" href="~/images/favicon.ico" type="image/x-icon" />
        <link type="text/css" rel="stylesheet" href="~/Styles/Site.css" />
        <script src="~/Scripts/jquery.watermark.js" type="text/javascript" language="javascript"></script>
        <script src="~/Scripts/jquery.fancybox-1.3.1.pack.js" type="text/javascript" language="javascript"></script>
    </head>
    <body>
        <use content="MainContent"></use>
        qualcosa ......
    </body>
</html>

Come potete vedere non è presente nessun codeblock a inizio pagina e le risorse tipo css, img, etc. posso essere specificate con il prefisso tilde ~/  , che verrà sostituito dall’engine di spark con la root del sito o con quello che ci è più congeniale.

Per ora ci basta creare la nostra master page e specificare i placeholder tramite il tag Use, che andremo a riutilizzare nel vista in questo modo:

<content name="MainContent">
    Benvenuto Spark!
</content>

Anche qui, come potete vedere, tutti i codeblock sono spariti a vantaggio della leggibilià e del numero ridotto di righe presenti all’inteno della view (fidatevi, questo non è nulla Smile).

asp.net comments edit

Ne avevo già parlato durante una sessione alla V UgiAlt.Net Conference, poi un lettore mi ha consigliato di inserirlo in Dexter e di parlarne un po’, così ho deciso di realizzare una serie di post su SparkViewEngine. Prima di partire con dei post tecnici su come utilizzare Spark e quali vantaggi offre, è giusto fare qualche premessa spiegando cos’è e a cosa serve :).

Spark View Engine è un template engine per ASP.NET MVC (sia versione 1.0 che versione 2.0) e Castle Project MonoRail che ha lo scopo di semplificare e potenziare la stesura del markup da parte dello sviluppatore o di colui che andrà a realizzare la “skin” della propria applicazione web.
Uno degli aspetti sicuramente più interessanti consiste nella possibilità di avere “View” miste, metà spark e metà MVC classiche e quindi ci permette di adottarlo anche in progetti già esistenti.
Con i post seguenti vedremo come Spark affronta il problema della realizzazione di codice HTML dinamico e capiremo il perchè Luis De Jardin lo ha definito un DSL; per ora ci basti pensare che è possibile ridurre, in alcuni casi anche dimezzare, il numero di righe di codice HTML/C# presenti all’interno delle nostre View, e di avere delle funzioni molto spinte come la renderizzazione di una View in formato PDF.

Stay tuned!

.net comments edit

Approfittando del giorno di vacanza mi sono messo a dare uno sguardo ai CodeContracts del .NET Framework 4.0. Per chi non li conoscesse, i CodeContracts non sono altro che un insieme di classi che permettono, grazie anche a dei tools che vanno installati, di definire delle regole di PreCondizione, PostCondizione e Invarianti di Oggetto per le nostre classi. Guardando un po’ il lato pratico, possiamo brevemente riassumere che:

  • Le PreCondizioni equivalgono alla validazione dei parametri di ingresso in un determinato metodo (es: l’oggetto foo non deve essere null);
  • Le PostCondizioni sono molto simili alle PreCondizioni, ma si rivolgono all’oggetto in uscita dal metodo;
  • Le Invarianti di Oggetto invece si rivolgono alle proprietà di un oggetto;

Un aspetto interessante è sicuramente la possibilità di specificare queste regole anche a delle interfacce, forse in maniera abbastanza “strana”, ma pensandoci su corretta. Di fatto, ci basta creare una classe che implementa l’interfaccia a cui vogliamo assegnare i nostri Contracts e decorarla con un apposito attributo; a questo punto il compilatore farà il resto, ossia inserire tutto il necessario su chi andrà ad implementare realmente l’interfaccia.
Inoltre, grazie ai tools (disponibili qui) viene generata automaticamente la documentazione in formato XML, che successivamente può essere data in pasto a SandCastle per averne un formato leggibile :).

Concludendo, devo dire che il primo approccio è sicuramente positivo e di fatto, dopo un po’ che ci “giocavo”, mi sono apparsi in mente diversi scenari in cui poter sfruttare questa nuova interessante feature e sicuramente ne nasceranno dei posts, quindi Stay tuned!

Ciauz!