<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:copyright="http://blogs.law.harvard.edu/tech/rss" xmlns:image="http://purl.org/rss/1.0/modules/image/">
    <channel>
        <title>ASP.NET 3.5</title>
        <link>http://blogs.ugidotnet.org:443/dsantarelli/category/ASP.NET 3.5.aspx</link>
        <description>ASP.NET 3.5</description>
        <language>it-IT</language>
        <copyright>Dario Santarelli</copyright>
        <generator>Subtext Version 2.6.0.0</generator>
        <item>
            <title>Slides su ASP.Net 3.5 SP1 Dynamic Data</title>
            <link>http://blogs.ugidotnet.org:443/dsantarelli/archive/2008/11/26/asp.net-3.5-sp1-dynamic-data.aspx</link>
            <description>Non che io sia un fan di ASP.NET Dynamic Data, tuttavia ho trovato &lt;a target="_blank" href="http://blogs.msdn.com/micham/archive/2008/11/26/asp-net-3-5-sp1-dynamic-data.aspx"&gt;questa presentazione&lt;/a&gt; molto utile per chi vuole avvicinarsi a questa tecnologia senza inciampare :D. &lt;br /&gt;
&lt;br /&gt;
Technorati Tag: &lt;a rel="tag" href="http://technorati.com/tags/ASP.NET"&gt;ASP.NET&lt;/a&gt;&lt;img src="http://blogs.ugidotnet.org:443/dsantarelli/aggbug/94765.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Dario Santarelli</dc:creator>
            <guid>http://blogs.ugidotnet.org:443/dsantarelli/archive/2008/11/26/asp.net-3.5-sp1-dynamic-data.aspx</guid>
            <pubDate>Wed, 26 Nov 2008 17:47:07 GMT</pubDate>
            <comments>http://blogs.ugidotnet.org:443/dsantarelli/archive/2008/11/26/asp.net-3.5-sp1-dynamic-data.aspx#feedback</comments>
            <wfw:commentRss>http://blogs.ugidotnet.org:443/dsantarelli/comments/commentRss/94765.aspx</wfw:commentRss>
            <trackback:ping>http://blogs.ugidotnet.org:443/dsantarelli/services/trackbacks/94765.aspx</trackback:ping>
        </item>
        <item>
            <title>[ASP.NET] PageAsyncTask e pagine asincrone</title>
            <link>http://blogs.ugidotnet.org:443/dsantarelli/archive/2008/11/08/asp.net-pageasynctask-e-pagine-asincrone.aspx</link>
            <description>&lt;p&gt;A partire da ASP.NET 2.0, la classe System.Web.UI.Page introduce un metodo non molto conosciuto in grado di facilitare la realizzazione di &lt;a href="http://i.msdn.microsoft.com/cc163725.fig02(en-us).gif" target="_blank"&gt;pagine asincrone&lt;/a&gt;: il metodo &lt;a href="http://msdn.microsoft.com/en-us/library/system.web.ui.page.registerasynctask.aspx" target="_blank"&gt;RegisterAsyncTask&lt;/a&gt;. Spesso mi è capitato di vedere implementare chiamate asincrone (es. invocazione di un WebService) in maniera non corretta sfruttando la logica dell' &lt;a href="http://msdn.microsoft.com/it-it/library/ba6dhx95(VS.80).aspx" target="_blank"&gt;AddOnPreRenderCompleteAsync&lt;/a&gt;, quando in realtà molti dei problemi potevano essere gestiti facilmente tramite Task asincroni, che in ASP.NET sono rappresentati dalla classe &lt;a href="http://msdn.microsoft.com/en-us/library/system.web.ui.pageasynctask.aspx" target="_blank"&gt;PageAsyncTask&lt;/a&gt;.    &lt;br /&gt;Le differenze tra i due approcci non sono moltissime ma significative. Infatti, entrambi richiedono &lt;span lang="EN-US" style="font-size: 8pt; line-height: 115%; font-family: 'Courier New'; mso-ansi-language: en-us; mso-no-proof: yes"&gt;&lt;span style="color: red"&gt;Async&lt;/span&gt;&lt;span style="color: blue"&gt;="true"&lt;/span&gt;&lt;/span&gt; nella direttiva @Page (o  &lt;span style="font-size: 8pt; line-height: 115%; font-family: " courier="" new="; mso-no-proof: yes"&gt;AsyncMode = &lt;span style="color: blue"&gt;true&lt;/span&gt;; &lt;/span&gt;da codice) e dunque la predisposizione all'esecuzione asincrona della pagina su thread diversi dopo il completamento del PreRender.     &lt;br /&gt;Tuttavia, il metodo RegisterAsyncTask introduce i seguenti vantaggi chiave:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;In aggiunta ai metodi Begin/End, permette di registrare un metodo per gestire il timeout di una operazione eventualmente troppo lunga. Il timeout è per-page ed è impostabile tramite l'attributo &lt;a href="http://msdn.microsoft.com/en-us/library/system.web.ui.page.asynctimeout.aspx" target="_blank"&gt;AsyncTimeout&lt;/a&gt; della direttiva @Page:  &lt;span lang="EN-US" style="font-size: 8pt; background: yellow; line-height: 115%; font-family: 'Courier New'; mso-highlight: yellow; mso-ansi-language: en-us; mso-no-proof: yes"&gt;&amp;lt;%&lt;/span&gt;&lt;span lang="EN-US" style="font-size: 8pt; color: blue; line-height: 115%; font-family: 'Courier New'; mso-ansi-language: en-us; mso-no-proof: yes"&gt;@&lt;/span&gt;&lt;span lang="EN-US" style="font-size: 8pt; line-height: 115%; font-family: 'Courier New'; mso-ansi-language: en-us; mso-no-proof: yes"&gt; &lt;span style="color: #a31515"&gt;Page&lt;/span&gt; &lt;/span&gt;&lt;span lang="EN-US" style="font-size: 8pt; line-height: 115%; font-family: 'Courier New'; mso-ansi-language: en-us; mso-no-proof: yes"&gt;&lt;span style="color: red"&gt;Async&lt;/span&gt;&lt;span style="color: blue"&gt;="true"&lt;/span&gt; &lt;span style="color: red"&gt;AsyncTimeout&lt;/span&gt;&lt;span style="color: blue"&gt;="10" ...&lt;/span&gt; &lt;span style="background: yellow; mso-highlight: yellow"&gt;%&amp;gt;&lt;/span&gt;&lt;/span&gt;  &lt;/li&gt;    &lt;li&gt;Permette di gestire più &lt;a href="http://msdn.microsoft.com/en-us/library/system.web.ui.pageasynctask.aspx" target="_blank"&gt;PageAsyncTask&lt;/a&gt; (ovvero più "async points") all'interno di un ciclo di vita di una pagina asincrona. Questi a loro volta possono essere eseguiti sia in modalità sequenziale che in modalità parallela (grazie a &lt;a href="http://msdn.microsoft.com/it-it/library/ms153492.aspx" target="_blank"&gt;questo overload&lt;/a&gt; del contruttore di PageAsyncTask). Anche in questo caso, analogamente al pattern &lt;a href="http://msdn.microsoft.com/it-it/library/55xs7d7f.aspx" target="_blank"&gt;MetodAsync/MethodCompleted&lt;/a&gt; disponibile per le classi proxy dei WS (dal framework 2.0 in poi), &lt;strong&gt;ASP.NET "ritarda" il rendering della pagina finché tutti i task asincroni non sono stati completati&lt;/strong&gt;.&lt;/li&gt;    &lt;li&gt;Permette di passare un oggetto 'state' ai nostri metodi BeginAsync tramite la classe PageAsyncTask. &lt;/li&gt;    &lt;li&gt;Permette di mantenere l'impersonation, la culture e l'oggetto HttpContext.Current nei metodi EndAsync e Timeout (cosa non prevista dal metodo EndAsync registrato con l'approccio AddOnPreRenderCompleteAsync)&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Mettiamo insieme il tutto e vediamo un esempio di applicazione dei PageAsyncTask.   &lt;br /&gt;Vogliamo elaborare dei feed RSS tramite PageAsyncTask diversi all'interno di una nostra pagina asincrona.&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-bottom: 0pt; line-height: normal; mso-layout-grid-align: none"&gt;&lt;span lang="EN-US" style="font-size: 8pt; color: blue; font-family: " courier="" new="; mso-ansi-language: EN-US; mso-no-proof: yes"&gt;public&lt;/span&gt;&lt;span lang="EN-US" style="font-size: 8pt; font-family: " courier="" new="; mso-ansi-language: EN-US; mso-no-proof: yes"&gt; &lt;span style="color: blue"&gt;partial&lt;/span&gt; &lt;span style="color: blue"&gt;class&lt;/span&gt; &lt;span style="color: #2b91af"&gt;SampleAsyncPage&lt;/span&gt; : System.Web.UI.&lt;span style="color: #2b91af"&gt;Page       &lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: 8pt; line-height: 115%; font-family: " courier="" new="; mso-no-proof: yes"&gt;{     &lt;br /&gt;&lt;/span&gt;&lt;span lang="EN-US" style="font-size: 8pt; color: blue; font-family: " courier="" new="; mso-ansi-language: EN-US; mso-no-proof: yes"&gt;     &lt;br /&gt;  protected&lt;/span&gt;&lt;span lang="EN-US" style="font-size: 8pt; font-family: " courier="" new="; mso-ansi-language: EN-US; mso-no-proof: yes"&gt; &lt;span style="color: blue"&gt;void&lt;/span&gt; Page_Load(&lt;span style="color: blue"&gt;object&lt;/span&gt; sender, &lt;span style="color: #2b91af"&gt;EventArgs&lt;/span&gt; e)      &lt;br /&gt;&lt;/span&gt;&lt;span lang="EN-US" style="font-size: 8pt; font-family: " courier="" new="; mso-ansi-language: EN-US; mso-no-proof: yes"&gt;  {     &lt;br /&gt;     &lt;/span&gt;&lt;span lang="EN-US" style="font-size: 8pt; font-family: " courier="" new="; mso-ansi-language: EN-US; mso-no-proof: yes"&gt;&lt;span style="color: #2b91af"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="color: blue"&gt;string&lt;/span&gt;&amp;gt; feeds = &lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="color: blue"&gt;string&lt;/span&gt;&amp;gt;();      &lt;br /&gt;     &lt;/span&gt;&lt;span lang="EN-US" style="font-size: 8pt; font-family: " courier="" new="; mso-ansi-language: EN-US; mso-no-proof: yes"&gt;feeds.Add(&lt;span style="color: #a31515"&gt;"http://blogs.msdn.com/MainFeed.aspx?Type=AllBlogs"&lt;/span&gt;);      &lt;br /&gt;&lt;/span&gt;&lt;span lang="EN-US" style="font-size: 8pt; font-family: " courier="" new="; mso-ansi-language: EN-US; mso-no-proof: yes"&gt;     feeds.Add(&lt;span style="color: #a31515"&gt;"http://blogs.ugidotnet.org/MainFeed.aspx"&lt;/span&gt;);      &lt;br /&gt;&lt;/span&gt;&lt;span lang="EN-US" style="font-size: 8pt; font-family: " courier="" new="; mso-ansi-language: EN-US; mso-no-proof: yes"&gt;     feeds.Add(&lt;span style="color: #a31515"&gt;"http://channel9.msdn.com/Feeds/RSS/"&lt;/span&gt;);&lt;span style="mso-spacerun: yes"&gt;        &lt;br /&gt;        &lt;br /&gt;     &lt;/span&gt;&lt;/span&gt;&lt;span lang="EN-US" style="font-size: 8pt; font-family: " courier="" new="; mso-ansi-language: EN-US; mso-no-proof: yes"&gt;&lt;span style="color: blue"&gt;foreach&lt;/span&gt; (&lt;span style="color: blue"&gt;string&lt;/span&gt; feed &lt;span style="color: blue"&gt;in&lt;/span&gt; feeds)      &lt;br /&gt;     &lt;/span&gt;&lt;span lang="EN-US" style="font-size: 8pt; font-family: " courier="" new="; mso-ansi-language: EN-US; mso-no-proof: yes"&gt;{     &lt;br /&gt;       &lt;/span&gt;&lt;span lang="EN-US" style="font-size: 8pt; font-family: " courier="" new="; mso-ansi-language: EN-US; mso-no-proof: yes"&gt;RegisterAsyncTask(&lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;PageAsyncTask&lt;/span&gt;(&lt;/span&gt;&lt;span lang="EN-US" style="font-size: 8pt; font-family: " courier="" new="; mso-ansi-language: EN-US; mso-no-proof: yes"&gt;&lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;BeginEventHandler&lt;/span&gt;(BeginAsyncOperation), &lt;span style="color: green"&gt;// BeginAsync&lt;/span&gt;      &lt;br /&gt;                                           &lt;/span&gt;&lt;span lang="EN-US" style="font-size: 8pt; font-family: " courier="" new="; mso-ansi-language: EN-US; mso-no-proof: yes"&gt;&lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;EndEventHandler&lt;/span&gt;(EndAsyncOperation), &lt;span style="color: green"&gt;// EndAsync&lt;/span&gt;      &lt;br /&gt;                                           &lt;/span&gt;&lt;span lang="EN-US" style="font-size: 8pt; font-family: " courier="" new="; mso-ansi-language: EN-US; mso-no-proof: yes"&gt;&lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;EndEventHandler&lt;/span&gt;(TimeoutAsyncOperation), &lt;span style="color: green"&gt;// TimeoutAsync&lt;/span&gt;      &lt;br /&gt;                                           &lt;/span&gt;&lt;span style="font-size: 8pt; color: #2b91af; font-family: " courier="" new="; mso-no-proof: yes"&gt;WebRequest&lt;/span&gt;&lt;span style="font-size: 8pt; font-family: " courier="" new="; mso-no-proof: yes"&gt;.Create(feed), &lt;span style="color: green"&gt;// State&lt;/span&gt;      &lt;br /&gt;                                           &lt;/span&gt;&lt;span style="font-size: 8pt; font-family: " courier="" new="; mso-no-proof: yes"&gt;&lt;span style="color: blue"&gt;true&lt;/span&gt; &lt;span style="color: green"&gt;// I task registrati verranno eseguiti in parallelo       &lt;br /&gt;                                          &lt;/span&gt;&lt;/span&gt;&lt;span lang="EN-US" style="font-size: 8pt; font-family: " courier="" new="; mso-ansi-language: EN-US; mso-no-proof: yes"&gt;)     &lt;br /&gt;                        &lt;/span&gt;&lt;span lang="EN-US" style="font-size: 8pt; font-family: " courier="" new="; mso-ansi-language: EN-US; mso-no-proof: yes"&gt;);&lt;span style="mso-spacerun: yes"&gt;            &lt;br /&gt;     &lt;/span&gt;&lt;/span&gt;&lt;span lang="EN-US" style="font-size: 8pt; font-family: " courier="" new="; mso-ansi-language: EN-US; mso-no-proof: yes"&gt;}&lt;span style="mso-spacerun: yes"&gt;        &lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span lang="EN-US" style="font-size: 8pt; font-family: " courier="" new="; mso-ansi-language: EN-US; mso-no-proof: yes"&gt;  }     &lt;p /&gt;   &lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-bottom: 0pt; line-height: normal; mso-layout-grid-align: none"&gt;&lt;span lang="EN-US" style="font-size: 8pt; font-family: " courier="" new="; mso-ansi-language: EN-US; mso-no-proof: yes"&gt;&lt;span style="color: #2b91af"&gt;  IAsyncResult&lt;/span&gt; BeginAsyncOperation(&lt;span style="color: blue"&gt;object&lt;/span&gt; sender, &lt;span style="color: #2b91af"&gt;EventArgs&lt;/span&gt; e, &lt;span style="color: #2b91af"&gt;AsyncCallback&lt;/span&gt; callback, &lt;span style="color: blue"&gt;object&lt;/span&gt; state)      &lt;br /&gt;&lt;/span&gt;&lt;span lang="EN-US" style="font-size: 8pt; font-family: " courier="" new="; mso-ansi-language: EN-US; mso-no-proof: yes"&gt;  {     &lt;br /&gt;&lt;span style="color: green"&gt;    // In rawFeed abbiamo il feed RSS...&lt;/span&gt;      &lt;br /&gt;    &lt;/span&gt;&lt;span lang="EN-US" style="font-size: 8pt; font-family: " courier="" new="; mso-ansi-language: EN-US; mso-no-proof: yes"&gt;&lt;span style="color: #2b91af"&gt;WebRequest&lt;/span&gt; webRequest = (&lt;span style="color: #2b91af"&gt;WebRequest&lt;/span&gt;)state;      &lt;br /&gt;    &lt;/span&gt;&lt;span lang="EN-US" style="font-size: 8pt; font-family: " courier="" new="; mso-ansi-language: EN-US; mso-no-proof: yes"&gt;&lt;span style="color: blue"&gt;return&lt;/span&gt; webRequest.BeginGetResponse(callback, state);      &lt;br /&gt;&lt;/span&gt;&lt;span lang="EN-US" style="font-size: 8pt; font-family: " courier="" new="; mso-ansi-language: EN-US; mso-no-proof: yes"&gt;  }     &lt;br /&gt;      &lt;br /&gt;&lt;/span&gt;&lt;span lang="EN-US" style="font-size: 8pt; font-family: " courier="" new="; mso-ansi-language: EN-US; mso-no-proof: yes"&gt;&lt;span style="color: blue"&gt;  void&lt;/span&gt; EndAsyncOperation(&lt;span style="color: #2b91af"&gt;IAsyncResult&lt;/span&gt; ar)      &lt;br /&gt;&lt;/span&gt;&lt;span lang="EN-US" style="font-size: 8pt; font-family: " courier="" new="; mso-ansi-language: EN-US; mso-no-proof: yes"&gt;  {&lt;span style="mso-spacerun: yes"&gt;                &lt;br /&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span lang="EN-US" style="font-size: 8pt; font-family: " courier="" new="; mso-ansi-language: EN-US; mso-no-proof: yes"&gt;&lt;span style="color: #2b91af"&gt;WebRequest&lt;/span&gt; webrequest = (&lt;span style="color: #2b91af"&gt;WebRequest&lt;/span&gt;)ar.AsyncState;      &lt;br /&gt;    &lt;/span&gt;&lt;span lang="EN-US" style="font-size: 8pt; font-family: " courier="" new="; mso-ansi-language: EN-US; mso-no-proof: yes"&gt;&lt;span style="color: blue"&gt;string&lt;/span&gt; rawFeed = &lt;span style="color: blue"&gt;null&lt;/span&gt;;      &lt;br /&gt;  &lt;br /&gt;    &lt;/span&gt;&lt;span lang="EN-US" style="font-size: 8pt; font-family: " courier="" new="; mso-ansi-language: EN-US; mso-no-proof: yes"&gt;&lt;span style="color: blue"&gt;using&lt;/span&gt; (&lt;span style="color: #2b91af"&gt;WebResponse&lt;/span&gt; response = webrequest.EndGetResponse(ar))      &lt;br /&gt;    &lt;/span&gt;&lt;span lang="EN-US" style="font-size: 8pt; font-family: " courier="" new="; mso-ansi-language: EN-US; mso-no-proof: yes"&gt;{     &lt;br /&gt;      &lt;/span&gt;&lt;span lang="EN-US" style="font-size: 8pt; font-family: " courier="" new="; mso-ansi-language: EN-US; mso-no-proof: yes"&gt;&lt;span style="color: blue"&gt;using&lt;/span&gt; (&lt;span style="color: #2b91af"&gt;StreamReader&lt;/span&gt; reader = &lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;StreamReader&lt;/span&gt;(response.GetResponseStream())) rawFeed = reader.ReadToEnd();&lt;span style="mso-spacerun: yes"&gt;            &lt;br /&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span lang="EN-US" style="font-size: 8pt; font-family: " courier="" new="; mso-ansi-language: EN-US; mso-no-proof: yes"&gt;}&lt;span style="mso-spacerun: yes"&gt;         &lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span lang="EN-US" style="font-size: 8pt; font-family: " courier="" new="; mso-ansi-language: EN-US; mso-no-proof: yes"&gt;&lt;span style="mso-spacerun: yes"&gt;    &lt;/span&gt;&lt;span style="color: green"&gt;// In rawFeed abbiamo il feed RSS...       &lt;br /&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span lang="EN-US" style="font-size: 8pt; font-family: " courier="" new="; mso-ansi-language: EN-US; mso-no-proof: yes"&gt;}     &lt;br /&gt;      &lt;br /&gt;&lt;/span&gt;&lt;span lang="EN-US" style="font-size: 8pt; font-family: " courier="" new="; mso-ansi-language: EN-US; mso-no-proof: yes"&gt;&lt;span style="color: blue"&gt;  void&lt;/span&gt; TimeoutAsyncOperation(&lt;span style="color: #2b91af"&gt;IAsyncResult&lt;/span&gt; ar)      &lt;br /&gt;&lt;/span&gt;&lt;span lang="EN-US" style="font-size: 8pt; font-family: " courier="" new="; mso-ansi-language: EN-US; mso-no-proof: yes"&gt;  {     &lt;br /&gt;    &lt;/span&gt;&lt;span lang="EN-US" style="font-size: 8pt; font-family: " courier="" new="; mso-ansi-language: EN-US; mso-no-proof: yes"&gt;&lt;span style="color: green"&gt;// Gestione del Timeout per l' AsyncTask&lt;span style="mso-spacerun: yes"&gt;     &lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: 8pt; line-height: 115%; font-family: " courier="" new="; mso-no-proof: yes"&gt;  }     &lt;br /&gt;&lt;span style="font-size: 8pt; line-height: 115%; font-family: 'Courier New'; mso-no-proof: yes"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span lang="EN-US" style="mso-ansi-language: en-us"&gt;     &lt;p /&gt;   &lt;/span&gt;&lt;/p&gt;  &lt;p&gt;Per ciascun feed di un nostro elenco registriamo a livello di pagina un PageAsyncTask che in fase di esecuzione si occuperà di reperire lo stream del feed associato (ad esempio grazie alla classe &lt;a href="http://msdn.microsoft.com/en-us/library/system.net.webrequest.aspx" target="_blank"&gt;System.Net.WebRequest&lt;/a&gt;). Il miglioramento delle prestazioni è garantito anche dal fatto che l'esecuzione asincrona di ciascun Task verrà gestita da ASP.NET possibilmente in parallelo.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Considerazioni:&lt;/strong&gt;&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Se abbiamo bisogno di una pagina asincrona che gestisca un'unica chiamata asincrona, allora gli approcci AddOnPreRenderCompleteAsync e RegisterAsyncTask sono pressoché equivalenti. Ma se le chiamate asincrone sono molte, è decisamente consigliabile sfruttare le facilitazioni introdotte da RegisterAsyncTask. &lt;/li&gt;    &lt;li&gt;Il timeout è per-page e non per-call. Non possiamo cioè assegnare timeout diversi a chiamate asincrone diverse!!! Al massimo possiamo eventualmente modificare a runtime la proprietà AsyncTimeout, il che ovviamente non è la stessa cosa :D&lt;/li&gt;    &lt;li&gt;In combinazione con async ADO.NET (es. SqlCommand.BeginExecuteReader) ed in generale con le feature asincrone del framework .NET, le pagine ASP.NET asincrone offrono soluzioni molto convenienti per risolvere comuni problemi di I/O legati a scenari che inibiscono la scalabilità.&lt;/li&gt;    &lt;li&gt;In generale non è consigliabile/sicuro gestire operazioni asincrone in ASP.NET utilizzando le API System.Threading (es. &lt;a href="http://msdn.microsoft.com/en-us/library/system.threading.threadpool.queueuserworkitem.aspx" target="_blank"&gt;ThreadPool.QueueUserWorkItem&lt;/a&gt;). Il rischio infatti è quello di "rubare" thread alla normale gestione del ThreadPool di ASP.NET, ottenendo effetti che potrebbero risultare addirittura controproducenti.&lt;/li&gt; &lt;/ul&gt;  &lt;div class="wlWriterSmartContent" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:eb4400c9-5d15-4d25-8365-5a9409241fc0" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;Technorati Tag: &lt;a href="http://technorati.com/tags/ASP.NET" rel="tag"&gt;ASP.NET&lt;/a&gt;,&lt;a href="http://technorati.com/tags/PageAsyncTask" rel="tag"&gt;PageAsyncTask&lt;/a&gt;&lt;/div&gt;&lt;img src="http://blogs.ugidotnet.org:443/dsantarelli/aggbug/94555.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Dario Santarelli</dc:creator>
            <guid>http://blogs.ugidotnet.org:443/dsantarelli/archive/2008/11/08/asp.net-pageasynctask-e-pagine-asincrone.aspx</guid>
            <pubDate>Sat, 08 Nov 2008 15:23:00 GMT</pubDate>
            <comments>http://blogs.ugidotnet.org:443/dsantarelli/archive/2008/11/08/asp.net-pageasynctask-e-pagine-asincrone.aspx#feedback</comments>
            <wfw:commentRss>http://blogs.ugidotnet.org:443/dsantarelli/comments/commentRss/94555.aspx</wfw:commentRss>
            <trackback:ping>http://blogs.ugidotnet.org:443/dsantarelli/services/trackbacks/94555.aspx</trackback:ping>
        </item>
        <item>
            <title>[ASP.NET 3.5] AJAX History</title>
            <link>http://blogs.ugidotnet.org:443/dsantarelli/archive/2008/10/23/asp.net-3.5-ajax-history.aspx</link>
            <description>&lt;p&gt;ASP.NET 3.5 SP1 introduce un enanchement del controllo &lt;a href="http://msdn.microsoft.com/it-it/library/system.web.ui.scriptmanager.aspx" target="_blank"&gt;ScriptManager&lt;/a&gt; che permette di gestire degli stati di navigazione all'interno di una pagina AJAX-enabled accedibili mediante i pulsanti standard "Avanti/Indietro" del browser. In due parole: "Ajax History". Questa funzionalità fu inizialmente introdotta nel vecchio "&lt;a href="http://www.asp.net/Downloads/futures/" target="_blank"&gt;ASP.NET Futures&lt;/a&gt;" mediante il controllo &lt;em&gt;History&lt;/em&gt; (in passato scrissi anche un &lt;a href="http://blogs.ugidotnet.org/dsantarelli/archive/2007/09/10/asp.net-futures-il-controllo-history.aspx" target="_blank"&gt;post&lt;/a&gt; a riguardo).     &lt;br /&gt;La questione è tutt'altro che banale: poiché un browser attiva i meccanismi di navigazione in base al cambio dell' URL, in caso di richieste AJAX che non redirigono verso URL diverse, il browser non aggiorna l' history cache, precludendo all'utente il corretto utilizzo dei pulsanti di navigazione per i diversi stati che desidereremmo impostare nella nostre pagine AJAX-enabled.     &lt;br /&gt;La gestione dell' AJAX History non è abilitata di default, tuttavia è molto semplice da implementare. L'unico problema è stabilire che tipo di implementazione ha senso in base alla user experience che si vuole ottenere ed in base al comportamento dei controlli AJAX che si trovano nella nostra pagina.     &lt;br /&gt;Partiamo da un classico esempio: Database Northwind, visualizzazione di Products in una GridView ed una DropDownList con AutoPostBack="True" che filtra i Products in base alla Category selezionata. Il tutto piazzato dentro un &lt;em&gt;UpdatePanel&lt;/em&gt;.     &lt;br /&gt;    &lt;br /&gt;&lt;img src="http://img296.imageshack.us/img296/7168/immagine1kb5.jpg" /&gt;     &lt;br /&gt;    &lt;br /&gt;Senza la gestione dell'history, ogni volta che selezioniamo un Item della DropDownList i dati nella GridView vengono sì aggiornati correttamente, ma se volessimo tenere traccia delle nostre selezioni come stati diversi (navigabili tramite i pulsanti standard "Avanti/Indietro" del browser) dovremmo gestire degli &lt;strong&gt;history point&lt;/strong&gt;, che inoltre ci permettono di rendere eventualmente "bookmarkabili" i vari stati memorizzati, proprio come se fossero pagine diverse. Vediamo come:     &lt;br /&gt;    &lt;br /&gt;&lt;em&gt;&lt;strong&gt;1. Impostare EnableHistory="true" nello ScriptManager&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;  &lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;asp:ScriptManager&lt;/span&gt; &lt;span class="attr"&gt;ID&lt;/span&gt;&lt;span class="kwrd"&gt;="scriptManager_Main"&lt;/span&gt; &lt;span class="attr"&gt;runat&lt;/span&gt;&lt;span class="kwrd"&gt;="server"&lt;/span&gt; &lt;strong&gt;&lt;span class="attr"&gt;EnableHistory&lt;/span&gt;&lt;span class="kwrd"&gt;="true"&lt;/span&gt;&lt;/strong&gt; &lt;br /&gt;                   &lt;span class="attr"&gt;&lt;strong&gt;EnableSecureHistoryState&lt;/strong&gt;&lt;/span&gt;&lt;span class="kwrd"&gt;&lt;strong&gt;="true|false"&lt;/strong&gt; &lt;/span&gt;&lt;span class="attr"&gt;OnNavigate&lt;/span&gt;&lt;span class="kwrd"&gt;="scriptManager_Main_Navigate"&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;style type="text/css"&gt;&lt;![CDATA[


.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }]]&gt;&lt;/style&gt;

&lt;p&gt;L'evento &lt;em&gt;OnNavigate&lt;/em&gt; viene scatenato quando viene premuto un pulsante di navigazione del browser, mentre la proprietà &lt;a href="http://msdn.microsoft.com/it-it/library/system.web.ui.scriptmanager.enablesecurehistorystate.aspx" target="_blank"&gt;EnableSecureHistoryState&lt;/a&gt; ci permette di cifrare o meno l'URL associata ad ogni HistoryPoint.  Di queste cose ne parliamo tra pochissimo. 

  &lt;br /&gt;

  &lt;br /&gt;&lt;em&gt;&lt;strong&gt;2. Gestire il  salvataggio degli History point&lt;/strong&gt;&lt;/em&gt; 

  &lt;br /&gt;In uno scenario come quello di esempio, quando selezioniamo una categoria nella DropDownList (evento &lt;em&gt;SelectedIndexChanged&lt;/em&gt;), decidiamo si salvare un nuovo history point, poichè di fatto rappresenta uno stato "isolabile" in cui si trova la pagina.&lt;/p&gt;

&lt;p class="MsoNormal" style="margin-bottom: 0pt; line-height: normal; mso-layout-grid-align: none"&gt;&lt;span style="font-size: 8pt; color: green; font-family: " courier="courier" new?;="new?;" mso-no-proof:="mso-no-proof:" yes?="yes?"&gt;// Creazione di un History Point se: 
    &lt;br /&gt;&lt;/span&gt;&lt;span style="font-size: 8pt; font-family: " courier="courier" new?;="new?;" mso-no-proof:="mso-no-proof:" yes?="yes?"&gt;&lt;span style="color: green"&gt;// 1. Il PostBack avviene in modalità PartialRendering 
      &lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: 8pt; font-family: " courier="courier" new?;="new?;" mso-no-proof:="mso-no-proof:" yes?="yes?"&gt;&lt;span style="color: green"&gt;// 2. Non si stanno utilizzando i pulsanti di navigazione del browser 
      &lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: 8pt; font-family: " courier="courier" new?;="new?;" mso-no-proof:="mso-no-proof:" yes?="yes?"&gt;&lt;span style="color: green"&gt;// 3. E' selezionato un valore non blank della DropDownList &lt;/span&gt;&lt;/span&gt;

  &lt;/p&gt;&lt;p /&gt;


&lt;p /&gt;

&lt;p /&gt;

&lt;p class="MsoNormal" style="margin-bottom: 0pt; line-height: normal; mso-layout-grid-align: none"&gt;&lt;span lang="EN-US" style="font-size: 8pt; color: blue; font-family: " courier="courier" new?;="new?;" mso-no-proof:="mso-no-proof:" yes;="yes;" mso-ansi-language:="mso-ansi-language:" en-us?="EN-US?"&gt;protected&lt;/span&gt;&lt;span lang="EN-US" style="font-size: 8pt; font-family: " courier="courier" new?;="new?;" mso-no-proof:="mso-no-proof:" yes;="yes;" mso-ansi-language:="mso-ansi-language:" en-us?="EN-US?"&gt; &lt;span style="color: blue"&gt;void&lt;/span&gt; ddlProductsCategories_SelectedIndexChanged(&lt;span style="color: blue"&gt;object&lt;/span&gt; sender, &lt;span style="color: #2b91af"&gt;EventArgs&lt;/span&gt; e) 

    &lt;br /&gt;&lt;/span&gt;&lt;span lang="EN-US" style="font-size: 8pt; font-family: " courier="courier" new?;="new?;" mso-no-proof:="mso-no-proof:" yes;="yes;" mso-ansi-language:="mso-ansi-language:" en-us?="EN-US?"&gt;{ 
    &lt;br /&gt;  &lt;/span&gt;&lt;span lang="EN-US" style="font-size: 8pt; font-family: " courier="courier" new?;="new?;" mso-no-proof:="mso-no-proof:" yes;="yes;" mso-ansi-language:="mso-ansi-language:" en-us?="EN-US?"&gt;&lt;span style="color: blue"&gt;if&lt;/span&gt; (scriptManager_Main.IsInAsyncPostBack &amp;amp;&amp;amp; !scriptManager_Main.IsNavigating 

    &lt;br /&gt;      &lt;/span&gt;&lt;span lang="EN-US" style="font-size: 8pt; font-family: " courier="courier" new?;="new?;" mso-no-proof:="mso-no-proof:" yes;="yes;" mso-ansi-language:="mso-ansi-language:" en-us?="EN-US?"&gt;&amp;amp;&amp;amp; ddlProductsCategories.SelectedIndex &amp;gt; 0) 
    &lt;br /&gt;  &lt;/span&gt;&lt;span lang="EN-US" style="font-size: 8pt; font-family: " courier="courier" new?;="new?;" mso-no-proof:="mso-no-proof:" yes;="yes;" mso-ansi-language:="mso-ansi-language:" en-us?="EN-US?"&gt;{ 
    &lt;br /&gt;    &lt;/span&gt;&lt;span lang="EN-US" style="font-size: 8pt; font-family: " courier="courier" new?;="new?;" mso-no-proof:="mso-no-proof:" yes;="yes;" mso-ansi-language:="mso-ansi-language:" en-us?="EN-US?"&gt;scriptManager_Main.AddHistoryPoint(&lt;span style="color: #a31515"&gt;"category"&lt;/span&gt;, ddlProductsCategories.SelectedIndex.ToString(), &lt;span style="color: blue"&gt;this&lt;/span&gt;.Title); 

    &lt;br /&gt;  &lt;/span&gt;&lt;span style="font-size: 8pt; font-family: " courier="courier" new?;="new?;" mso-no-proof:="mso-no-proof:" yes?="yes?"&gt;} 
    &lt;br /&gt;&lt;/span&gt;&lt;span style="font-size: 8pt; line-height: 115%; font-family: " courier="courier" new?;="new?;" mso-no-proof:="mso-no-proof:" yes?="yes?"&gt;}&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;
  &lt;br /&gt;In questo caso notiamo come l'overload utilizzato del metodo &lt;a href="http://msdn.microsoft.com/it-it/library/cc472959.aspx" target="_blank"&gt;AddHistoryPoint&lt;/a&gt; permetta di associare al nuovo HistoryPoint un titolo, che possiamo usare eventualmente come titolo della pagina. 

  &lt;br /&gt;

  &lt;br /&gt;&lt;strong&gt;&lt;em&gt;3. Gestire dell'evento Navigate dello ScriptManager&lt;/em&gt;&lt;/strong&gt; 

  &lt;br /&gt;Grazie a questo evento possiamo impostare uno degli stati salvati grazie alla proprietà &lt;em&gt;State&lt;/em&gt; dell' &lt;a href="http://msdn.microsoft.com/it-it/library/system.web.ui.historyeventargs.aspx" target="_blank"&gt;HistoryEventArgs&lt;/a&gt;, inizializzata automaticamente da ASP.NET grazie al parsing della querystring.&lt;/p&gt;

&lt;p class="MsoNormal" style="margin-bottom: 0pt; line-height: normal; mso-layout-grid-align: none"&gt;&lt;span lang="EN-US" style="font-size: 8pt; font-family: " courier="courier" new?;="new?;" mso-no-proof:="mso-no-proof:" yes;="yes;" mso-ansi-language:="mso-ansi-language:" en-us?="EN-US?"&gt;&lt;span style="color: blue"&gt;protected&lt;/span&gt; &lt;span style="color: blue"&gt;void&lt;/span&gt; scriptManager_Main_Navigate(&lt;span style="color: blue"&gt;object&lt;/span&gt; sender, &lt;span style="color: #2b91af"&gt;HistoryEventArgs&lt;/span&gt; e) 

    &lt;br /&gt;&lt;/span&gt;&lt;span lang="EN-US" style="font-size: 8pt; font-family: " courier="courier" new?;="new?;" mso-no-proof:="mso-no-proof:" yes;="yes;" mso-ansi-language:="mso-ansi-language:" en-us?="EN-US?"&gt;{ 
    &lt;br /&gt;  &lt;/span&gt;&lt;span lang="EN-US" style="font-size: 8pt; font-family: " courier="courier" new?;="new?;" mso-no-proof:="mso-no-proof:" yes;="yes;" mso-ansi-language:="mso-ansi-language:" en-us?="EN-US?"&gt;&lt;span style="color: blue"&gt;string&lt;/span&gt; categoryID = e.State[&lt;span style="color: #a31515"&gt;"category"&lt;/span&gt;]; 

    &lt;br /&gt;  &lt;/span&gt;&lt;span lang="EN-US" style="font-size: 8pt; font-family: " courier="courier" new?;="new?;" mso-no-proof:="mso-no-proof:" yes;="yes;" mso-ansi-language:="mso-ansi-language:" en-us?="EN-US?"&gt;&lt;span style="color: blue"&gt;if&lt;/span&gt; (&lt;span style="color: blue"&gt;string&lt;/span&gt;.IsNullOrEmpty(categoryID)) ddlProductsCategories.SelectedIndex = 0; 

    &lt;br /&gt;  &lt;/span&gt;&lt;span lang="EN-US" style="font-size: 8pt; font-family: " courier="courier" new?;="new?;" mso-no-proof:="mso-no-proof:" yes;="yes;" mso-ansi-language:="mso-ansi-language:" en-us?="EN-US?"&gt;&lt;span style="color: blue"&gt;else&lt;/span&gt; ddlProductsCategories.SelectedIndex = &lt;span style="color: #2b91af"&gt;Convert&lt;/span&gt;.ToInt32(categoryID);&lt;span style="mso-spacerun: yes"&gt;                    &lt;br /&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: 8pt; font-family: " courier="courier" new?;="new?;" mso-no-proof:="mso-no-proof:" yes?="yes?"&gt;updatePanel_Products.Update();&lt;span style="mso-spacerun: yes"&gt;        &lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: 8pt; line-height: 115%; font-family: " courier="courier" new?;="new?;" mso-no-proof:="mso-no-proof:" yes?="yes?"&gt;}&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;
      &lt;br /&gt;4. Gestione della proprietà EnableSecureHistoryState dello ScriptManager&lt;/em&gt;&lt;/strong&gt; 

  &lt;br /&gt;Quando un utente memorizza un nuovo HistoryPoint, automaticamente ASP.NET genera un'unica URL manipolando la querystring, che il browser salva opportunamente in modo tale da renderla navigabile: 

  &lt;br /&gt;

  &lt;br /&gt;&lt;img src="http://img260.imageshack.us/img260/6704/immagine2el4.jpg" /&gt; 

  &lt;br /&gt;  &lt;br /&gt;A questo punto la proprietà &lt;a href="http://msdn.microsoft.com/it-it/library/system.web.ui.scriptmanager.enablesecurehistorystate.aspx" target="_blank"&gt;EnableSecureHistoryState&lt;/a&gt; ci permette di stabilire in via definitiva se l'URL oggetto dell'HistoryPoint possa o meno essere resa leggibile dall'utente, poiché nel primo caso potrebbe generare un problema di security (ricordiamoci che la querystring esporrebbe le informazioni di stato). Per questo motivo, di default la proprietà &lt;em&gt;EnableSecureHistoryState&lt;/em&gt; è impostata a true, generando un URL cifrata del tipo: 

  &lt;br /&gt;

  &lt;br /&gt;&lt;em&gt;http://localhost:49526/WebSite1/Default.aspx#&amp;amp;&amp;amp;DwIbkbGQcKwH...&lt;/em&gt; 

  &lt;br /&gt;&lt;/p&gt;

&lt;div class="wlWriterSmartContent" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:62ab3bdc-c86a-4b96-b182-7846dee79997" style="padding-right: 0px; display: inline; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;Technorati Tag: &lt;a href="http://technorati.com/tags/AJAX" rel="tag"&gt;AJAX&lt;/a&gt;,&lt;a href="http://technorati.com/tags/ASP.NET" rel="tag"&gt;ASP.NET&lt;/a&gt;&lt;/div&gt;&lt;img src="http://blogs.ugidotnet.org:443/dsantarelli/aggbug/94352.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Dario Santarelli</dc:creator>
            <guid>http://blogs.ugidotnet.org:443/dsantarelli/archive/2008/10/23/asp.net-3.5-ajax-history.aspx</guid>
            <pubDate>Thu, 23 Oct 2008 09:12:40 GMT</pubDate>
            <comments>http://blogs.ugidotnet.org:443/dsantarelli/archive/2008/10/23/asp.net-3.5-ajax-history.aspx#feedback</comments>
            <wfw:commentRss>http://blogs.ugidotnet.org:443/dsantarelli/comments/commentRss/94352.aspx</wfw:commentRss>
            <trackback:ping>http://blogs.ugidotnet.org:443/dsantarelli/services/trackbacks/94352.aspx</trackback:ping>
        </item>
        <item>
            <title>Serializzazione JSON con DataContractJsonSerializer</title>
            <link>http://blogs.ugidotnet.org:443/dsantarelli/archive/2008/09/23/serializzazione-json-con-datacontractjsonserializer.aspx</link>
            <description>&lt;p&gt;Una delle novità introdotte dal Framework 3.5 nell' ambito dello sviluppo in AJAX è l'introduzione della classe &lt;a href="http://msdn.microsoft.com/en-us/library/system.runtime.serialization.json.datacontractjsonserializer.aspx" target="_blank"&gt;DataContractJsonSerializer&lt;/a&gt;, che di fatto sostituisce la classe &lt;a href="http://msdn.microsoft.com/en-us/library/system.web.script.serialization.javascriptserializer.aspx" target="_blank"&gt;JavaScriptSerializer&lt;/a&gt; (messa a disposizione dalle precedenti AJAX Extensions 1.0 per ASP.NET 2.0) nella serializzazione/deserializzazione di oggetti &lt;a href="http://www.json.org/" target="_blank"&gt;JSON&lt;/a&gt;. Utilizzando tali extensions la serializzazione/deserializzazione in/da una rappresentazione JSON poteva essere ottenuta in maniera molto semplice con un paio di righe di codice:     &lt;br /&gt;    &lt;br /&gt;&lt;span lang="EN-US" style="font-size: 8pt; color: blue; line-height: 115%; font-family: " yes?="yes?" mso-no-proof:="mso-no-proof:" en-us;="EN-US;" mso-ansi-language:="mso-ansi-language:" new?;="new?;" courier="courier"&gt;using&lt;/span&gt;&lt;span lang="EN-US" style="font-size: 8pt; line-height: 115%; font-family: " yes?="yes?" mso-no-proof:="mso-no-proof:" en-us;="EN-US;" mso-ansi-language:="mso-ansi-language:" new?;="new?;" courier="courier"&gt; System.Web.Script.Serialization;      &lt;br /&gt;      &lt;br /&gt;&lt;/span&gt;&lt;span lang="EN-US" style="font-size: 8pt; color: #2b91af; font-family: " yes?="yes?" mso-no-proof:="mso-no-proof:" en-us;="EN-US;" mso-ansi-language:="mso-ansi-language:" new?;="new?;" courier="courier"&gt;Customer&lt;/span&gt;&lt;span lang="EN-US" style="font-size: 8pt; font-family: " yes?="yes?" mso-no-proof:="mso-no-proof:" en-us;="EN-US;" mso-ansi-language:="mso-ansi-language:" new?;="new?;" courier="courier"&gt; customer = &lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;Customer&lt;/span&gt;() { Name = &lt;span style="color: #a31515"&gt;"Dario Santarelli"&lt;/span&gt;, Address = &lt;span style="color: #a31515"&gt;"via Pippo 10"&lt;/span&gt;, Email = &lt;span style="color: #a31515"&gt;"xxx@yyy.zz"&lt;/span&gt; };       &lt;br /&gt;&lt;/span&gt;&lt;span lang="EN-US" style="font-size: 8pt; font-family: " yes?="yes?" mso-no-proof:="mso-no-proof:" en-us;="EN-US;" mso-ansi-language:="mso-ansi-language:" new?;="new?;" courier="courier"&gt;&lt;span style="color: #2b91af"&gt;JavaScriptSerializer&lt;/span&gt; javascriptSerializer = &lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;JavaScriptSerializer&lt;/span&gt;();       &lt;br /&gt;&lt;/span&gt;&lt;span style="font-size: 8pt; color: #2b91af; line-height: 115%; font-family: " yes?="yes?" mso-no-proof:="mso-no-proof:" new?;="new?;" courier="courier"&gt;Console&lt;/span&gt;&lt;span style="font-size: 8pt; line-height: 115%; font-family: " yes?="yes?" mso-no-proof:="mso-no-proof:" new?;="new?;" courier="courier"&gt;.WriteLine(javascriptSerializer.Serialize(customer));&lt;span style="mso-spacerun: yes"&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span lang="EN-US" style="font-size: 8pt; line-height: 115%; font-family: " yes?="yes?" mso-no-proof:="mso-no-proof:" en-us;="EN-US;" mso-ansi-language:="mso-ansi-language:" new?;="new?;" courier="courier"&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;   &lt;br /&gt;Oggi invece l'introduzione della classe DataContractJsonSerializer rende obsoleto l'utilizzo del JavascriptSerializer, consigliando invece un' implementazione leggermente diversa dalla precedente. Ad esempio:     &lt;br /&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span lang="EN-US" style="font-size: 8pt; color: blue; line-height: 115%; font-family: " yes?="yes?" mso-no-proof:="mso-no-proof:" en-us;="EN-US;" mso-ansi-language:="mso-ansi-language:" new?;="new?;" courier="courier"&gt;using&lt;/span&gt;&lt;span lang="EN-US" style="font-size: 8pt; line-height: 115%; font-family: " yes?="yes?" mso-no-proof:="mso-no-proof:" en-us;="EN-US;" mso-ansi-language:="mso-ansi-language:" new?;="new?;" courier="courier"&gt; System.Runtime.Serialization.Json;      &lt;br /&gt;&lt;/span&gt;&lt;span lang="EN-US" style="font-size: 8pt; color: #2b91af; font-family: " yes?="yes?" mso-no-proof:="mso-no-proof:" en-us;="EN-US;" mso-ansi-language:="mso-ansi-language:" new?;="new?;" courier="courier"&gt;     &lt;br /&gt;Customer&lt;/span&gt;&lt;span lang="EN-US" style="font-size: 8pt; font-family: " yes?="yes?" mso-no-proof:="mso-no-proof:" en-us;="EN-US;" mso-ansi-language:="mso-ansi-language:" new?;="new?;" courier="courier"&gt; customer = &lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;Customer&lt;/span&gt;() { Name = &lt;span style="color: #a31515"&gt;"Dario Santarelli"&lt;/span&gt;, Address = &lt;span style="color: #a31515"&gt;"via Pippo 10"&lt;/span&gt;, Email = &lt;span style="color: #a31515"&gt;"xxx@yyy.zz"&lt;/span&gt; };       &lt;br /&gt;&lt;/span&gt;&lt;span lang="EN-US" style="font-size: 8pt; font-family: " yes?="yes?" mso-no-proof:="mso-no-proof:" en-us;="EN-US;" mso-ansi-language:="mso-ansi-language:" new?;="new?;" courier="courier"&gt;&lt;span style="color: #2b91af"&gt;DataContractJsonSerializer&lt;/span&gt; serializer = &lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;DataContractJsonSerializer&lt;/span&gt;(customer.GetType());       &lt;br /&gt;&lt;/span&gt;&lt;span lang="EN-US" style="font-size: 8pt; font-family: " yes?="yes?" mso-no-proof:="mso-no-proof:" en-us;="EN-US;" mso-ansi-language:="mso-ansi-language:" new?;="new?;" courier="courier"&gt;&lt;span style="color: #2b91af"&gt;MemoryStream&lt;/span&gt; stream = &lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;MemoryStream&lt;/span&gt;();       &lt;br /&gt;&lt;/span&gt;&lt;span lang="EN-US" style="font-size: 8pt; font-family: " yes?="yes?" mso-no-proof:="mso-no-proof:" en-us;="EN-US;" mso-ansi-language:="mso-ansi-language:" new?;="new?;" courier="courier"&gt;serializer.WriteObject(stream, customer);      &lt;br /&gt;&lt;/span&gt;&lt;span lang="EN-US" style="font-size: 8pt; font-family: " yes?="yes?" mso-no-proof:="mso-no-proof:" en-us;="EN-US;" mso-ansi-language:="mso-ansi-language:" new?;="new?;" courier="courier"&gt;&lt;span style="color: blue"&gt;string&lt;/span&gt; json = &lt;span style="color: #2b91af"&gt;Encoding&lt;/span&gt;.UTF8.GetString(stream.ToArray());       &lt;br /&gt;&lt;/span&gt;&lt;span style="font-size: 8pt; color: #2b91af; line-height: 115%; font-family: " yes?="yes?" mso-no-proof:="mso-no-proof:" new?;="new?;" courier="courier"&gt;Console&lt;/span&gt;&lt;span style="font-size: 8pt; line-height: 115%; font-family: " yes?="yes?" mso-no-proof:="mso-no-proof:" new?;="new?;" courier="courier"&gt;.WriteLine(json);&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;   &lt;br /&gt;Qual'è la differenza tra i due scenari? Per rispondere occorre addentrasi maggiormente nella questione.     &lt;br /&gt;Analogamente a quanto richiesto per utilizzo della classe JavaScriptSerializer, al fine di serializzare un oggetto in una stringa JSON tramite DataContractJsonSerializer dobbiamo anzitutto marcare la classe corrispondente come serializzabile. Abbiamo quindi due scelte: possiamo decorare la nostra classe &lt;em&gt;Customer&lt;/em&gt; con l'attributo &lt;em&gt;Serializable&lt;/em&gt; oppure con l'attributo &lt;em&gt;DataContract &lt;/em&gt;(specificando ovviamente l'attributo &lt;em&gt;DataMember &lt;/em&gt;per le proprietà di interesse).     &lt;br /&gt;Riassumendo, potremmo implementare la nostra classe &lt;em&gt;Customer&lt;/em&gt; in due modi diversi, ottenendo però risultati di serializzazione diversi in base al tipo di Serializer scelto.&lt;/p&gt;  &lt;table cellspacing="2" cellpadding="2" width="100%" border="0"&gt;&lt;tbody&gt;     &lt;tr&gt;       &lt;td valign="top" width="456"&gt;         &lt;p class="MsoNormal" style="margin-bottom: 0pt; line-height: normal; mso-layout-grid-align: none"&gt;&lt;span lang="EN-US" style="font-size: 8pt; font-family: " yes?="yes?" mso-no-proof:="mso-no-proof:" en-us;="EN-US;" mso-ansi-language:="mso-ansi-language:" new?;="new?;" courier="courier"&gt;[&lt;span style="color: #2b91af"&gt;Serializable&lt;/span&gt;]               &lt;br /&gt;&lt;/span&gt;&lt;span lang="EN-US" style="font-size: 8pt; font-family: " yes?="yes?" mso-no-proof:="mso-no-proof:" en-us;="EN-US;" mso-ansi-language:="mso-ansi-language:" new?;="new?;" courier="courier"&gt;&lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: blue"&gt;class&lt;/span&gt; &lt;span style="color: #2b91af"&gt;Customer &lt;/span&gt;&lt;/span&gt;&lt;span lang="EN-US" style="font-size: 8pt; font-family: " yes?="yes?" mso-no-proof:="mso-no-proof:" en-us;="EN-US;" mso-ansi-language:="mso-ansi-language:" new?;="new?;" courier="courier"&gt;&lt;span style="mso-spacerun: yes"&gt;  &lt;br /&gt;&lt;/span&gt;{               &lt;br /&gt;  &lt;/span&gt;&lt;span lang="EN-US" style="font-size: 8pt; font-family: " yes?="yes?" mso-no-proof:="mso-no-proof:" en-us;="EN-US;" mso-ansi-language:="mso-ansi-language:" new?;="new?;" courier="courier"&gt;&lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: blue"&gt;string&lt;/span&gt; Name { &lt;span style="color: blue"&gt;get&lt;/span&gt;; &lt;span style="color: blue"&gt;set&lt;/span&gt;; }               &lt;br /&gt;  &lt;/span&gt;&lt;span lang="EN-US" style="font-size: 8pt; font-family: " yes?="yes?" mso-no-proof:="mso-no-proof:" en-us;="EN-US;" mso-ansi-language:="mso-ansi-language:" new?;="new?;" courier="courier"&gt;&lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: blue"&gt;string&lt;/span&gt; Address { &lt;span style="color: blue"&gt;get&lt;/span&gt;; &lt;span style="color: blue"&gt;set&lt;/span&gt;; }               &lt;br /&gt;  &lt;/span&gt;&lt;span lang="EN-US" style="font-size: 8pt; font-family: " yes?="yes?" mso-no-proof:="mso-no-proof:" en-us;="EN-US;" mso-ansi-language:="mso-ansi-language:" new?;="new?;" courier="courier"&gt;&lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: blue"&gt;string&lt;/span&gt; Email { &lt;span style="color: blue"&gt;get&lt;/span&gt;; &lt;span style="color: blue"&gt;set&lt;/span&gt;; }               &lt;br /&gt;&lt;/span&gt;&lt;span style="font-size: 8pt; line-height: 115%; font-family: " yes?="yes?" mso-no-proof:="mso-no-proof:" new?;="new?;" courier="courier"&gt;}              &lt;br /&gt;              &lt;br /&gt;&lt;strong&gt;Serializzazione JSON tramite DataContractJsonSerializer &lt;/strong&gt;:  &lt;br /&gt;              &lt;br /&gt;{"&amp;lt;Address&amp;gt;k__BackingField":"via Pippo 10","&amp;lt;Email&amp;gt;k__BackingField":"xxx@yyy.zz",               &lt;br /&gt;"&amp;lt;Name&amp;gt;k__BackingField":"Dario Santarelli"}               &lt;br /&gt;&lt;/span&gt;&lt;/p&gt;          &lt;p class="MsoNormal" style="margin-bottom: 0pt; line-height: normal; mso-layout-grid-align: none"&gt;&lt;span style="font-size: 8pt; line-height: 115%; font-family: " yes?="yes?" mso-no-proof:="mso-no-proof:" new?;="new?;" courier="courier"&gt;&lt;strong&gt;Serializzazione JSON tramite JavaScriptSerializer&lt;/strong&gt;:               &lt;br /&gt;&lt;/span&gt;&lt;span style="font-size: 8pt; line-height: 115%; font-family: " yes?="yes?" mso-no-proof:="mso-no-proof:" new?;="new?;" courier="courier"&gt;             &lt;br /&gt;{"Name":"Dario Santarelli","Address":"via Pippo 10","Email":"xxx@yyy.zz"} &lt;/span&gt;&lt;/p&gt;       &lt;/td&gt;        &lt;td valign="top" width="661"&gt;         &lt;p class="MsoNormal" style="margin-bottom: 0pt; line-height: normal; mso-layout-grid-align: none"&gt;&lt;span lang="EN-US" style="font-size: 8pt; font-family: " yes?="yes?" mso-no-proof:="mso-no-proof:" en-us;="EN-US;" mso-ansi-language:="mso-ansi-language:" new?;="new?;" courier="courier"&gt;[&lt;span style="color: #2b91af"&gt;DataContract&lt;/span&gt;]               &lt;br /&gt;&lt;/span&gt;&lt;span lang="EN-US" style="font-size: 8pt; font-family: " yes?="yes?" mso-no-proof:="mso-no-proof:" en-us;="EN-US;" mso-ansi-language:="mso-ansi-language:" new?;="new?;" courier="courier"&gt;&lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: blue"&gt;class&lt;/span&gt; &lt;span style="color: #2b91af"&gt;Customer                &lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span lang="EN-US" style="font-size: 8pt; font-family: " yes?="yes?" mso-no-proof:="mso-no-proof:" en-us;="EN-US;" mso-ansi-language:="mso-ansi-language:" new?;="new?;" courier="courier"&gt;{              &lt;br /&gt;  &lt;/span&gt;&lt;span lang="EN-US" style="font-size: 8pt; font-family: " yes?="yes?" mso-no-proof:="mso-no-proof:" en-us;="EN-US;" mso-ansi-language:="mso-ansi-language:" new?;="new?;" courier="courier"&gt;[&lt;span style="color: #2b91af"&gt;DataMember&lt;/span&gt;(Name=&lt;span style="color: #a31515"&gt;"FullName"&lt;/span&gt;)]               &lt;br /&gt;  &lt;/span&gt;&lt;span lang="EN-US" style="font-size: 8pt; font-family: " yes?="yes?" mso-no-proof:="mso-no-proof:" en-us;="EN-US;" mso-ansi-language:="mso-ansi-language:" new?;="new?;" courier="courier"&gt;&lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: blue"&gt;string&lt;/span&gt; Name { &lt;span style="color: blue"&gt;get&lt;/span&gt;; &lt;span style="color: blue"&gt;set&lt;/span&gt;; }               &lt;br /&gt;              &lt;br /&gt;  &lt;/span&gt;&lt;span lang="EN-US" style="font-size: 8pt; font-family: " yes?="yes?" mso-no-proof:="mso-no-proof:" en-us;="EN-US;" mso-ansi-language:="mso-ansi-language:" new?;="new?;" courier="courier"&gt;[&lt;span style="color: #2b91af"&gt;DataMember&lt;/span&gt;(Name = &lt;span style="color: #a31515"&gt;"HomeAddress"&lt;/span&gt;)]               &lt;br /&gt;  &lt;/span&gt;&lt;span lang="EN-US" style="font-size: 8pt; font-family: " yes?="yes?" mso-no-proof:="mso-no-proof:" en-us;="EN-US;" mso-ansi-language:="mso-ansi-language:" new?;="new?;" courier="courier"&gt;&lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: blue"&gt;string&lt;/span&gt; Address { &lt;span style="color: blue"&gt;get&lt;/span&gt;; &lt;span style="color: blue"&gt;set&lt;/span&gt;; }               &lt;br /&gt;              &lt;br /&gt;  &lt;/span&gt;&lt;span lang="EN-US" style="font-size: 8pt; font-family: " yes?="yes?" mso-no-proof:="mso-no-proof:" en-us;="EN-US;" mso-ansi-language:="mso-ansi-language:" new?;="new?;" courier="courier"&gt;[&lt;span style="color: #2b91af"&gt;DataMember&lt;/span&gt;]               &lt;br /&gt;  &lt;/span&gt;&lt;span lang="EN-US" style="font-size: 8pt; font-family: " yes?="yes?" mso-no-proof:="mso-no-proof:" en-us;="EN-US;" mso-ansi-language:="mso-ansi-language:" new?;="new?;" courier="courier"&gt;&lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: blue"&gt;string&lt;/span&gt; Email { &lt;span style="color: blue"&gt;get&lt;/span&gt;; &lt;span style="color: blue"&gt;set&lt;/span&gt;; }               &lt;br /&gt;&lt;/span&gt;&lt;span style="font-size: 8pt; line-height: 115%; font-family: " yes?="yes?" mso-no-proof:="mso-no-proof:" new?;="new?;" courier="courier"&gt;}              &lt;br /&gt;&lt;/span&gt;&lt;span style="font-size: 8pt; line-height: 115%; font-family: " yes?="yes?" mso-no-proof:="mso-no-proof:" new?;="new?;" courier="courier"&gt;&lt;strong&gt;&lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;          &lt;p class="MsoNormal" style="margin-bottom: 0pt; line-height: normal; mso-layout-grid-align: none"&gt;&lt;span style="font-size: 8pt; line-height: 115%; font-family: " yes?="yes?" mso-no-proof:="mso-no-proof:" new?;="new?;" courier="courier"&gt;             &lt;br /&gt;&lt;strong&gt;Serializzazione JSON tramite DataContractJsonSerializer&lt;/strong&gt;:               &lt;br /&gt;              &lt;br /&gt;{"Email":"xxx@yyy.zz","FullName":"Dario Santarelli","HomeAddress":"via Pippo 10" }               &lt;br /&gt;              &lt;br /&gt;&lt;/span&gt;&lt;span style="font-size: 8pt; line-height: 115%; font-family: " yes?="yes?" mso-no-proof:="mso-no-proof:" new?;="new?;" courier="courier"&gt;&lt;strong&gt;Serializzazione JSON tramite JavaScriptSerializer&lt;/strong&gt;:               &lt;br /&gt;&lt;/span&gt;&lt;span style="font-size: 8pt; line-height: 115%; font-family: " yes?="yes?" mso-no-proof:="mso-no-proof:" new?;="new?;" courier="courier"&gt;             &lt;br /&gt;{"Name":"Dario Santarelli","Address":"via Pippo 10","Email":"xxx@yyy.zz"} &lt;/span&gt;&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;   &lt;/tbody&gt;&lt;/table&gt;  &lt;p&gt;Da questo esempio vanno estrapolati due importanti aspetti:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;La serializzazione via DataContractJsonSerializer di un oggetto marcato come &lt;em&gt;Serializable&lt;/em&gt; restituisce un output JSON in realtà non compatibile con il serializer client-side di ASP.NET AJAX. &lt;/li&gt;    &lt;li&gt;L'eventuale aliasing delle proprietà da serializzare tramite l'uso della proprietà &lt;em&gt;Name&lt;/em&gt; dell'attributo &lt;em&gt;DataMember&lt;/em&gt; si ripercuote nella generazione della corrispondente rappresentazione JSON da parte del DataContractJsonSerializer, a differenza di quanto accade con l'utilizzo del JavaScriptSerializer.       &lt;br /&gt;&lt;/li&gt; &lt;/ol&gt;  &lt;div class="wlWriterSmartContent" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:acbaa6b6-41ee-4786-b775-b099dce2151d" style="padding-right: 0px; display: inline; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;Technorati Tag: &lt;a href="http://technorati.com/tags/AJAX" rel="tag"&gt;AJAX&lt;/a&gt;,&lt;a href="http://technorati.com/tags/ASP.NET" rel="tag"&gt;ASP.NET&lt;/a&gt;&lt;/div&gt;&lt;img src="http://blogs.ugidotnet.org:443/dsantarelli/aggbug/94119.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Dario Santarelli</dc:creator>
            <guid>http://blogs.ugidotnet.org:443/dsantarelli/archive/2008/09/23/serializzazione-json-con-datacontractjsonserializer.aspx</guid>
            <pubDate>Tue, 23 Sep 2008 00:27:52 GMT</pubDate>
            <comments>http://blogs.ugidotnet.org:443/dsantarelli/archive/2008/09/23/serializzazione-json-con-datacontractjsonserializer.aspx#feedback</comments>
            <wfw:commentRss>http://blogs.ugidotnet.org:443/dsantarelli/comments/commentRss/94119.aspx</wfw:commentRss>
            <trackback:ping>http://blogs.ugidotnet.org:443/dsantarelli/services/trackbacks/94119.aspx</trackback:ping>
        </item>
        <item>
            <title>[ASP.NET 3.5] GridView e DataPager</title>
            <link>http://blogs.ugidotnet.org:443/dsantarelli/archive/2008/08/08/asp.net-3.5-gridview-e-datapager.aspx</link>
            <description>&lt;p&gt;Uno dei nuovi controlli che troviamo nel tab "Data" della ToolBox di VS2008 è il &lt;a href="http://msdn.microsoft.com/it-it/library/system.web.ui.webcontrols.datapager.aspx" target="_blank"&gt;DataPager&lt;/a&gt;. L'interessante funzionalità che esso introduce riguarda la gestione del paging per tutti i controlli "bindabili" che implementano l'interfaccia &lt;a href="http://msdn.microsoft.com/it-it/library/system.web.ui.webcontrols.ipageableitemcontainer.aspx"&gt;IPageableItemContainer&lt;/a&gt;. In VS2008 l'unico controllo che risponde di default a tale requisito è il controllo &lt;a href="http://msdn.microsoft.com/it-it/library/system.web.ui.webcontrols.listview.aspx" target="_blank"&gt;ListView&lt;/a&gt;.     &lt;br /&gt;Dunque, se da una parte il ListView e il DataPager costituiscono un' accoppiata già precostituita, dall'altra possiamo adoperarci per "adattare" gli altri data controls (come il GridView) affinchè supportino la paginazione tramite il DataPager. Come è facile intuire, ciò può avvenire estendendo opportunamente tali controlli in modo che implementino l'interfaccia IPageableItemContainer.     &lt;br /&gt;Domanda: " Il controllo GridView possiede già un meccanismo built-in di paginazione.... Perché dovrei aver bisogno del DataPager? "    &lt;br /&gt;In effetti, il DataPager non introduce qualcosa che prima non si riusciva a fare se non con molto sforzo... tuttavia ci rende più produttivi in un bel po' di situazioni!!! Anzitutto, la separazione tra il gestore della paginazione e il controllo che visualizza i dati ci permette di posizionare i due componenti in punti differenti della pagina. Inoltre, per la stessa GridView possiamo prevedere più pagers che assumono il medesimo comportamento indipendentemente da quale utilizziamo per spostarci avanti/indietro nella visualizzazione dei dati. Un'altra comoda feature messa a disposizione dal DataPager riguarda la possibilità di ottenere la paginazione via QueryString (GET) o via PostBack (POST) semplicemente impostando la proprietà &lt;a href="http://msdn.microsoft.com/it-it/library/system.web.ui.webcontrols.datapager.querystringfield.aspx" target="_blank"&gt;QuerysStringField&lt;/a&gt; (più DataPager possono quindi essere "sincronizzati" se utilizzano lo stesso parametro della QueryString). Per ultimo, ma non per importanza, il &lt;a href="http://msdn.microsoft.com/it-it/library/system.web.ui.webcontrols.templatepagerfield.aspx" target="_blank"&gt;TemplatePagerField&lt;/a&gt; ci permette di modificare a nostro piacimento il layout del DataPager.    &lt;br /&gt;    &lt;br /&gt;In generale, estendere un controllo associabile a dati (es. Repeater, DataList, GridView etc.) per permettere l' interfacciamento con il DataPager non è un compito poi così difficile, ma di certo implica la conoscenza dei meccanismi di databind dei controlli ASP.NET in gioco ;).     &lt;br /&gt;    &lt;br /&gt;Per chi volesse approfondire la questione, consiglio la lettura di questi due ottimi articoli che mostrano due possibili implementazioni di una GridView abilitata al supporto del DataPager:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;a href="http://mattberseth.com/blog/2008/04/using_a_datapager_with_the_gri.html" target="_blank"&gt;Using a DataPager with the GridView Control - Implementing IPageableItemContainer&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://blogs.visoftinc.com/archive/2008/03/19/Extending-the-GridView-to-Work-With-the-New-DataPager-Control.aspx" target="_blank"&gt;Extending the GridView to work with the new DataPager Control&lt;/a&gt; &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;   &lt;br /&gt;Technorati tags: &lt;img alt=" " src="http://static.technorati.com/static/img/pub/icon-utag-16x13.png?tag=GridView" /&gt;&lt;a href="http://technorati.com/tags/GridView/"&gt;GridView&lt;/a&gt;, &lt;img alt=" " src="http://static.technorati.com/static/img/pub/icon-utag-16x13.png?tag=DataPager" /&gt;&lt;a href="http://technorati.com/tags/DataPager/"&gt;DataPager&lt;/a&gt;&lt;/p&gt;&lt;img src="http://blogs.ugidotnet.org:443/dsantarelli/aggbug/93656.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Dario Santarelli</dc:creator>
            <guid>http://blogs.ugidotnet.org:443/dsantarelli/archive/2008/08/08/asp.net-3.5-gridview-e-datapager.aspx</guid>
            <pubDate>Fri, 08 Aug 2008 11:46:57 GMT</pubDate>
            <comments>http://blogs.ugidotnet.org:443/dsantarelli/archive/2008/08/08/asp.net-3.5-gridview-e-datapager.aspx#feedback</comments>
            <wfw:commentRss>http://blogs.ugidotnet.org:443/dsantarelli/comments/commentRss/93656.aspx</wfw:commentRss>
            <trackback:ping>http://blogs.ugidotnet.org:443/dsantarelli/services/trackbacks/93656.aspx</trackback:ping>
        </item>
        <item>
            <title>Perch&amp;eacute; passare a soluzioni &amp;quot;ASP.NET REST-ful&amp;quot;... IMHO!!!</title>
            <link>http://blogs.ugidotnet.org:443/dsantarelli/archive/2008/06/23/percheacute-passare-a-soluzioni-quotasp.net-rest-fulquot.-imho.aspx</link>
            <description>&lt;p&gt;Sono ormai alcuni anni che mi occupo prevalentemente di sviluppo Web ed integrazione in ambienti distribuiti nell'ambito del B2B e devo dire che nel corso del tempo lo stile architetturale che mi ha convinto di più per riusabilità, scalabilità ed efficienza è &lt;a href="http://en.wikipedia.org/wiki/Representational_State_Transfer" target="_blank"&gt;REST&lt;/a&gt;. In questo blog ne ho parlato &lt;a href="http://blogs.ugidotnet.org/dsantarelli/archive/2007/11/07/altre-considerazioni-su-rest.aspx" target="_blank"&gt;una volta soltanto&lt;/a&gt;, partendo da alcune riflessioni non troppo entusiaste di altri blogger che evidenziavano GIUSTAMENTE il fatto che REST in realtà ha costituito per molti (me compreso) un 'modus operandi' ancor prima di sapere che si chiamasse così e che fosse collegato da molto tempo ad un vero e proprio "branch ufficioso" dello sviluppo Web. &lt;br /&gt;&lt;a href="http://blog.wekeroad.com" target="_blank"&gt;Rob Conery&lt;/a&gt; afferma: &lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;&lt;em&gt;"...the Web itself is the REST poster child. More accurately: REST is a state of mind&lt;strong&gt;...&lt;/strong&gt;" &lt;/em&gt;&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;In effetti REST (&lt;a href="http://en.wikipedia.org/wiki/Resource_oriented_architecture" target="_blank"&gt;ROA&lt;/a&gt; nel Web) esiste e "rivaleggia" con SOA da ormai molto tempo (una decina di anni se non di più) e da quanto ho avuto modo di osservare nella mia esperienza di sviluppatore Web, non è mai riuscito a sfondare nel mondo Enterprise in egual modo (almeno a livello di trend) rispetto al diretto concorrente. Non mi azzardo a supporre quale sia la spiegazione commerciale di questa cosa (anche perché attualmente non ho né le competenze né la conoscenza per farlo), tuttavia da quando ho iniziato a pensare REST-ful, secondo me il vero vantaggio che paga concretamente gli sforzi di implementazione ruota intorno a questo semplicissimo concetto:&lt;/p&gt; &lt;h4&gt;Uniformare le interfacce è meglio che specializzarle&lt;/h4&gt; &lt;p&gt;A differenza dell'approccio dei WS e in generale di SOA - ovvero promuovere appunto la specializzazione delle interfacce nonché i pattern e gli idiomi dei linguaggi di programmazione in un ambiente distribuito -, REST riduce ulteriormente l'accoppiamento funzionale tra client e server spostando il focus architetturale sulle risorse/entità, risolvendo elegantemente una marea di problemi di integrazione. &lt;br /&gt;In merito, due sono principalmente le obiezioni SOA-oriented che spesso sento affermare da colleghi/blogger: &lt;/p&gt; &lt;ul&gt; &lt;li&gt;Risorse differenti dovrebbero avere interfacce e metodi specifici affinché riflettano meglio le loro funzionalità  &lt;/li&gt;&lt;li&gt;REST è solo una traslazione dei problemi di (dis)accoppiamento funzionale al livello di scambio di messaggi tra client e server&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;Personalmente non sono molto d'accordo in entrambi i casi anzitutto perché sono convinto che gli effetti della distribuzione delle applicazioni nel Web sollevi nativamente dei problemi che possono essere risolti in maniera flessibile e scalabile solo da soluzioni REST-ful... partendo dalle "semplici" problematiche di performance (caching, latenza etc.), intermediazione (state management) e monitoraggio fino ad arrivare ai punti caldi della questione:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;strong&gt;Identificazione delle risorse tramite URI logici&lt;/strong&gt; (es. &lt;em&gt;http://.../myWebApp/Customers/[CustomerID]&lt;/em&gt;) che di fatto costituiscono una sorta di API ad alto livello di astrazione, implicando un netto miglioramento dell'accessibilità/comprensibilità/reperibilità per diverse figure professionali.  &lt;/li&gt;&lt;li&gt;&lt;strong&gt;La manipolazione delle risorse&lt;/strong&gt;, che avviene attraverso le stesse rappresentazioni in combinazione con l'uso dei verbi HTTP (GET, POST, PUT etc.) e &lt;strong&gt;NON va contro i principi dell'information hiding&lt;/strong&gt; (una rappresentazione di una risorsa non ne rivela alcun dettaglio implementativo)  &lt;/li&gt;&lt;li&gt;&lt;strong&gt;I messaggi tra client e server sono auto-descrittivi&lt;/strong&gt; e il relativo contenuto è rappresentabile mediante un qualunque &lt;a href="www.iana.org/assignments/media-types/" target="_blank"&gt;media types MIME&lt;/a&gt;, il che preserva nativamente lo sviluppatore dall'implementazione di codice ad-hoc per gestire specifici tipi di dati WSDL (se non IDL).  &lt;/li&gt;&lt;li&gt;&lt;strong&gt;Gli hypermedia stessi costituiscono il motore dello stato delle applicazioni&lt;/strong&gt;: questo approccio stabilisce definitivamente che &lt;strong&gt;le transizioni da uno stato ad un altro di una applicazione sono ESPLICITE e si trovano proprio all'interno della rappresentazione di uno stato e non all'interno della logica di metodi specifici di una o più interfacce esposte (transizioni IMPLICITE)&lt;/strong&gt;. &lt;br /&gt;Esempio: Supponiamo di avere la risorsa &lt;em&gt;http://.../myWebApp/Customers/List&lt;/em&gt; la quale elenca la lista dei clienti mediante degli HyperLink all'interno di una pagina XHTML, ognuno dei quali punta ad un' altra specifica risorsa del tipo &lt;em&gt;http://.../myWebApp/Customers/[CustomerID]&lt;/em&gt;. Ora, uno user agent che cerca le informazioni di uno specifico cliente ha solo il bisogno di seguire tali Hyperlink semplicemente controllando i dati e i metadati della rappresentazione della risorsa richiesta. In questo semplice caso, mantenere lo stato dell'applicazione nel client invece che sul server aumenta di molto la scalabilità.&lt;/li&gt;&lt;/ul&gt; &lt;h4&gt;ASP.NET e REST&lt;/h4&gt; &lt;p&gt;&lt;/p&gt; &lt;p&gt;Un aspetto su cui riflettere è che dopo tutto questo tempo Microsoft ha deciso di promuovere REST e ROA al 'grande pubblico', in concomitanza con l'uscita di Visual Studio 2008. Nella fattispecie, abbiamo assistito alla realizzazione di un framework ad-hoc per la creazione di applicazioni REST-ful con &lt;a href="http://www.asp.net/downloads/" target="_blank"&gt;ADO.NET Data Services&lt;/a&gt; (&lt;a href="http://astoria.mslivelabs.com/Default.aspx" target="_blank"&gt;progetto Astoria&lt;/a&gt; - prima come Extension e poi come feature inserita nella &lt;a href="http://www.asp.net/downloads/3.5-SP1/default.aspx" target="_blank"&gt;SP1 beta del Framework 3.5&lt;/a&gt; assieme all' &lt;a href="http://msdn.microsoft.com/en-us/library/bb399572.aspx" target="_blank"&gt;Entity Framework&lt;/a&gt;).&lt;br /&gt;Ma il fatto curioso che ho avuto modo di notare nella mia esperienza è che per molti sviluppatori ASP.NET, i principi di REST sono più percepiti nel pattern MVC piuttosto che nel framework ADO.NET Data Services dedicato. Un errore concettuale? Io sinceramente penso di no.&lt;br /&gt;In questo senso infatti sono assolutamente d'accordo con le riflessioni di &lt;a href="http://en.wikipedia.org/wiki/Dino_Esposito" target="_blank"&gt;Dino Esposito&lt;/a&gt; in questi due bellissimi post:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href="http://dotnetslackers.com/articles/aspnet/AnArchitecturalViewOfTheASPNETMVCFramework.aspx" target="_blank"&gt;An Architectural View of the ASP.NET MVC Framework&lt;/a&gt;  &lt;/li&gt;&lt;li&gt;&lt;a href="http://weblogs.asp.net/despos/archive/2007/11/07/devconn07-fall-mvc-fx-is-it-car-or-motorcycle.aspx" target="_blank"&gt;DevConn07 Fall:: MVC FX is it car or motorcycle?&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;le quali mi portano a pensare che la proclamazione definitiva di REST tra gli sviluppatori ASP.NET in fondo è da attribuire ANCHE all'introduzione degli aspetti REST-like del framework MVC. In particolare, ecco alcune frasi che mi sono piaciute molto:&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;&lt;em&gt;So what's IMHO the main aspect of the MVC framework? It uses a REST-like approach to ASP.NET Web development. It implements each request to the Web server as an HTTP call to something that can be logically described as a "remote service endpoint". ....  I see more REST than MVC in this model. And, more importantly, REST is a more appropriate pattern to describe what pages created with the MVC framework actually do.&lt;/em&gt;&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;E non è finita qui: oggi si possono prendere 'pezzi' dell' architettura ASP.NET MVC e fonderli nello sviluppo dei tradizionali Web Form (Classic ASP.NET). Ad esempio, il Routing delle Url (&lt;em&gt;System.Web.Routing&lt;/em&gt;) del framework MVC può essere calato nello sviluppo ASP.NET per implementare URL logiche in perfetto REST-style (ecco un &lt;a href="http://blogs.ugidotnet.org/dsantarelli/archive/2008/05/03/asp.net-routing-e-webforms-tradizionali.aspx" target="_blank"&gt;esempio&lt;/a&gt;). &lt;br /&gt;Mumble Mumble.... &lt;strong&gt;Domanda&lt;/strong&gt;: &lt;strong&gt;Classic ASP.NET e ASP.NET MVC Framework possono fondersi nel nome di REST ???&lt;br /&gt;&lt;/strong&gt;Se così fosse, ci troveremmo di fronte ad una situazione in cui, da un lato lo sviluppo ASP.NET viene fatto tendere verso soluzioni REST-ful by Design e dall'altro si rischia di 'sporcare' le best practice architetturali di REST e ROA magari per 'accomodare' soltanto alcuni aspetti specifici del mondo MVC nel mondo Classic ASP.NET (basato sul Postback model).&lt;br /&gt;&lt;br /&gt;Da perenne e incondizionato sostenitore di REST come standard de facto per l'accesso e l'elaborazione delle risorse nel Web, non posso che apprezzare gli sforzi di Microsoft degli ultimi tempi (e ritengo anche che varrebbe la pena investirci seriamente soprattutto nel settore Systems Integration) ma non posso neanche nascondere delle riserve sul grande ritardo che il paradigma ha avuto per quanto riguarda l'integrazione in Visual Studio ed in particolare in ASP.NET. &lt;/p&gt; &lt;p&gt;&lt;br /&gt;Technorati tags: &lt;img alt=" " src="http://static.technorati.com/static/img/pub/icon-utag-16x13.png?tag=REST" /&gt;&lt;a href="http://technorati.com/tags/REST/"&gt;REST&lt;/a&gt;, &lt;img alt=" " src="http://static.technorati.com/static/img/pub/icon-utag-16x13.png?tag=Astoria" /&gt;&lt;a href="http://technorati.com/tags/Astoria/"&gt;Astoria&lt;/a&gt;, &lt;img alt=" " src="http://static.technorati.com/static/img/pub/icon-utag-16x13.png?tag=MVC" /&gt;&lt;a href="http://technorati.com/tags/MVC/"&gt;MVC&lt;/a&gt;, &lt;img alt=" " src="http://static.technorati.com/static/img/pub/icon-utag-16x13.png?tag=ASP.NET" /&gt;&lt;a href="http://technorati.com/tags/ASP.NET/"&gt;ASP.NET&lt;/a&gt;&lt;/p&gt;&lt;img src="http://blogs.ugidotnet.org:443/dsantarelli/aggbug/93134.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Dario Santarelli</dc:creator>
            <guid>http://blogs.ugidotnet.org:443/dsantarelli/archive/2008/06/23/percheacute-passare-a-soluzioni-quotasp.net-rest-fulquot.-imho.aspx</guid>
            <pubDate>Mon, 23 Jun 2008 23:38:31 GMT</pubDate>
            <comments>http://blogs.ugidotnet.org:443/dsantarelli/archive/2008/06/23/percheacute-passare-a-soluzioni-quotasp.net-rest-fulquot.-imho.aspx#feedback</comments>
            <slash:comments>3</slash:comments>
            <wfw:commentRss>http://blogs.ugidotnet.org:443/dsantarelli/comments/commentRss/93134.aspx</wfw:commentRss>
            <trackback:ping>http://blogs.ugidotnet.org:443/dsantarelli/services/trackbacks/93134.aspx</trackback:ping>
        </item>
        <item>
            <title>ASP.NET Routing e WebForms tradizionali</title>
            <link>http://blogs.ugidotnet.org:443/dsantarelli/archive/2008/05/03/asp.net-routing-e-webforms-tradizionali.aspx</link>
            <description>&lt;p&gt;L'ultima release di &lt;a href="http://go.microsoft.com/fwlink/?LinkID=110956" target="_blank"&gt;ASP.NET MVC (Preview 2)&lt;/a&gt; fornisce alcune interessanti novità ed opportunità per gli sviluppatori ASP.NET. In particolare mi ha colpito molto la facilità di implementazione di meccanismi di routing che non siano più dipendenti dal framework MVC e che dunque possano essere facilmente integrati in progetti ASP.NET 'tradizionali'. Infatti, attualmente il framework Mvc è stato partizionato in tre assembly:  il solito System.Web.Mvc ed i nuovi &lt;em&gt;System.Web.Routing&lt;/em&gt; e &lt;em&gt;System.Web.Abstractions&lt;/em&gt;.&lt;br /&gt;Da un punto di vista pratico, uno degli usi sicuramente più ovvi delle funzionalità di routing riguarda la possibilità di realizzare qualcosa di alternativo all' &lt;a href="http://weblogs.asp.net/scottgu/archive/2007/02/26/tip-trick-url-rewriting-with-asp-net.aspx" target="_blank"&gt;Url Rewriting&lt;/a&gt; (&lt;strong&gt;Routing e Url Rewriting infatti non sono la stessa cosa (*)&lt;/strong&gt;): tutto ciò di cui abbiamo bisogno è creare anzitutto una classe che implementi l'interfaccia &lt;a href="http://weblogs.asp.net/fredriknormen/archive/2007/11/18/asp-net-mvc-framework-create-your-own-iroutehandler.aspx"&gt;IRouteHandler&lt;/a&gt; e quindi registrare nel Global.asax le nuove 'Routes' associate al nostro IRouteHandler. Vediamo un banale esempio di base:&lt;/p&gt; &lt;p&gt;&lt;br /&gt;&lt;span style="font-size: 8pt; color: blue; font-family: 'Courier New'"&gt;using&lt;/span&gt;&lt;span style="font-size: 8pt; font-family: 'Courier New'"&gt; System.Web.Routing;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-size: 8pt; color: blue; font-family: 'Courier New'"&gt;using&lt;/span&gt;&lt;span style="font-size: 8pt; font-family: 'Courier New'"&gt; System.Web.Compilation;&lt;?xml:namespace prefix = o /?&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="margin-bottom: 0pt; line-height: normal; mso-pagination: none; mso-layout-grid-align: none"&gt;&lt;span style="font-size: 8pt; font-family: 'Courier New'"&gt;&lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: blue"&gt;class&lt;/span&gt; &lt;span style="color: #2b91af"&gt;WebFormRouteHandler&lt;/span&gt; : &lt;span style="color: #2b91af"&gt;IRouteHandler&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: 8pt; font-family: 'Courier New'"&gt;{&lt;br /&gt;  &lt;/span&gt;&lt;span style="font-size: 8pt; font-family: 'Courier New'"&gt;&lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: blue"&gt;string&lt;/span&gt; VirtualPath { &lt;span style="color: blue"&gt;get&lt;/span&gt;; &lt;span style="color: blue"&gt;set&lt;/span&gt;; }&lt;br /&gt;  &lt;br /&gt;  &lt;/span&gt;&lt;span style="font-size: 8pt; font-family: 'Courier New'"&gt;&lt;span style="color: blue"&gt;public&lt;/span&gt; WebFormRouteHandler( &lt;span style="color: blue"&gt;string&lt;/span&gt; virtualPath ) { &lt;span style="color: blue"&gt;this&lt;/span&gt;.VirtualPath = virtualPath; }&lt;br /&gt;&lt;br /&gt;  &lt;/span&gt;&lt;span style="font-size: 8pt; color: blue; font-family: 'Courier New'"&gt;#region&lt;/span&gt;&lt;span style="font-size: 8pt; font-family: 'Courier New'"&gt; IRouteHandler Members&lt;br /&gt;&lt;br /&gt;    &lt;/span&gt;&lt;span style="font-size: 8pt; font-family: 'Courier New'"&gt;&lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: #2b91af"&gt;IHttpHandler&lt;/span&gt; GetHttpHandler(&lt;span style="color: #2b91af"&gt;RequestContext&lt;/span&gt; requestContext)&lt;br /&gt;    &lt;/span&gt;&lt;span style="font-size: 8pt; font-family: 'Courier New'"&gt;{&lt;br /&gt;       &lt;/span&gt;&lt;span style="font-size: 8pt; font-family: 'Courier New'"&gt;&lt;span style="color: blue"&gt;foreach&lt;/span&gt; (&lt;span style="color: blue"&gt;var&lt;/span&gt; value &lt;span style="color: blue"&gt;in&lt;/span&gt; requestContext.RouteData.Values)&lt;br /&gt;       &lt;/span&gt;&lt;span style="font-size: 8pt; font-family: 'Courier New'"&gt;{&lt;br /&gt;         &lt;/span&gt;&lt;span style="font-size: 8pt; font-family: 'Courier New'"&gt;requestContext.HttpContext.Items[value.Key] = value.Value;&lt;br /&gt;       &lt;/span&gt;&lt;span style="font-size: 8pt; font-family: 'Courier New'"&gt;}&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="margin-bottom: 0pt; line-height: normal; mso-pagination: none; mso-layout-grid-align: none"&gt;&lt;span style="font-size: 8pt; font-family: 'Courier New'"&gt;&lt;span style="mso-tab-count: 2"&gt;       &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: 8pt; font-family: 'Courier New'"&gt;&lt;span style="color: #2b91af"&gt;IHttpHandler&lt;/span&gt; page = (&lt;span style="color: #2b91af"&gt;IHttpHandler&lt;/span&gt;)&lt;span style="color: #2b91af"&gt;BuildManager&lt;/span&gt;.CreateInstanceFromVirtualPath(&lt;span style="color: blue"&gt;this&lt;/span&gt;.VirtualPath, &lt;span style="color: blue"&gt;typeof&lt;/span&gt;(&lt;span style="color: #2b91af"&gt;Page&lt;/span&gt;));&lt;span style="mso-spacerun: yes"&gt;            &lt;br /&gt;       &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: 8pt; font-family: 'Courier New'"&gt;&lt;span style="color: blue"&gt;return&lt;/span&gt; page;&lt;br /&gt;    &lt;/span&gt;&lt;span style="font-size: 8pt; font-family: 'Courier New'"&gt;}&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="margin-bottom: 0pt; line-height: normal; mso-pagination: none; mso-layout-grid-align: none"&gt;&lt;span style="font-size: 8pt; font-family: 'Courier New'"&gt;&lt;o:p&gt;   &lt;/o:p&gt;&lt;/span&gt;&lt;span style="font-size: 8pt; color: blue; font-family: 'Courier New'"&gt;#endregion&lt;br /&gt;&lt;/span&gt;&lt;span style="font-size: 8pt; font-family: 'Courier New'"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt; &lt;p&gt;Notiamo come l'unico metodo (GetHttpHandler) dell'interfaccia IRouteHandler prende in input il RequestContext (che nel mondo MVC viene solitamente acceduto tramite la proprietà &lt;em&gt;ControllerContext&lt;/em&gt; del Controller). Al suo interno, ci sono tutte le informazioni di routing estratte dall'URL (proprietà RouteData), che andiamo a 'copiare' nell'HttpContext affinchè siano utilizzabili all'interno delle nostre WebForms. &lt;br /&gt;Inoltre, nell'implementazione osserviamo l'utilizzo della classe statica &lt;a href="http://msdn2.microsoft.com/en-us/library/system.web.compilation.buildmanager.aspx" target="_blank"&gt;BuildManager&lt;/a&gt; che ci permette di istanziare una nostra Page (che implementa l'interfaccia IHttpHandler) partendo dal path virtuale.&lt;br /&gt;Analogamente a quanto avviene nel framework MVC, le Routes associate al nostro WebFormRouteHandler : IRouteHandler sono registrate nell'evento Application_Start del Global.asax:&lt;br /&gt;&lt;/p&gt;&lt;span style="font-size: 8pt; color: blue; font-family: 'Courier New'"&gt;using&lt;/span&gt;&lt;span style="font-size: 8pt; font-family: 'Courier New'"&gt; System.Web.Routing;&lt;br /&gt;&lt;/span&gt; &lt;p class="MsoNormal" style="margin-bottom: 0pt; line-height: normal; mso-pagination: none; mso-layout-grid-align: none"&gt;&lt;span style="font-size: 8pt; color: blue; font-family: 'Courier New'"&gt;public&lt;/span&gt;&lt;span style="font-size: 8pt; font-family: 'Courier New'"&gt; &lt;span style="color: blue"&gt;class&lt;/span&gt; &lt;span style="color: #2b91af"&gt;Global&lt;/span&gt; : System.Web.&lt;span style="color: #2b91af"&gt;HttpApplication&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: 8pt; font-family: 'Courier New'"&gt;{&lt;br /&gt;  &lt;/span&gt;&lt;span style="font-size: 8pt; font-family: 'Courier New'"&gt;&lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: blue"&gt;static&lt;/span&gt; &lt;span style="color: blue"&gt;void&lt;/span&gt; RegisterRoutes(&lt;span style="color: #2b91af"&gt;RouteCollection&lt;/span&gt; routes)&lt;br /&gt;  &lt;/span&gt;&lt;span style="font-size: 8pt; font-family: 'Courier New'"&gt;{&lt;br /&gt;    &lt;/span&gt;&lt;span style="font-size: 8pt; font-family: 'Courier New'"&gt;&lt;span style="color: blue"&gt;var&lt;/span&gt; detailsHandler = &lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;WebFormRouteHandler&lt;/span&gt;( &lt;span style="color: #a31515"&gt;"~/Details.aspx"&lt;/span&gt; );&lt;br /&gt;&lt;span style="mso-spacerun: yes"&gt;    &lt;/span&gt;routes.Add(&lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;Route&lt;/span&gt;(&lt;span style="color: #a31515"&gt;"category/{category}/item/{id}"&lt;/span&gt;, detailsHandler));&lt;/span&gt;&lt;span style="font-size: 8pt; font-family: 'Courier New'"&gt;&lt;span style="mso-tab-count: 5"&gt;                                  &lt;br /&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: 8pt; font-family: 'Courier New'"&gt;}&lt;br /&gt;&lt;span style="mso-spacerun: yes"&gt;  &lt;/span&gt;&lt;br /&gt;&lt;span style="mso-spacerun: yes"&gt;  &lt;/span&gt;&lt;span style="color: blue"&gt;protected&lt;/span&gt; &lt;span style="color: blue"&gt;void&lt;/span&gt; Application_Start( &lt;span style="color: blue"&gt;object&lt;/span&gt; sender, &lt;span style="color: #2b91af"&gt;EventArgs&lt;/span&gt; e )&lt;br /&gt;  &lt;/span&gt;&lt;span style="font-size: 8pt; font-family: 'Courier New'"&gt;{&lt;br /&gt;&lt;span style="mso-spacerun: yes"&gt;    &lt;/span&gt;RegisterRoutes(&lt;span style="color: #2b91af"&gt;RouteTable&lt;/span&gt;.Routes);&lt;br /&gt;&lt;span style="mso-spacerun: yes"&gt;  &lt;/span&gt;}&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="margin-bottom: 0pt; line-height: normal; mso-pagination: none; mso-layout-grid-align: none"&gt;&lt;span style="font-size: 8pt; font-family: 'Courier New'"&gt;&lt;o:p&gt;...&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="margin-bottom: 0pt; line-height: normal; mso-pagination: none; mso-layout-grid-align: none"&gt;&lt;span style="font-size: 8pt; font-family: 'Courier New'"&gt;}&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt; &lt;p&gt;&lt;br /&gt;A questo punto siamo pronti!&lt;br /&gt;Nelle nostre pagine ASPX recuperiamo i parametri contenuti nell'URL tramite la proprietà &lt;em&gt;HttpContext.Items ["&amp;lt;key&amp;gt;"] &lt;/em&gt;(che esiste solamente nel ciclo di vita della singola pagina). Ad esempio: &lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: 8pt; font-family: 'Courier New'"&gt;&lt;span style="color: blue"&gt;protected&lt;/span&gt; &lt;span style="color: blue"&gt;void&lt;/span&gt; Page_Load( &lt;span style="color: blue"&gt;object&lt;/span&gt; sender, &lt;span style="color: #2b91af"&gt;EventArgs&lt;/span&gt; e )&lt;br /&gt;&lt;/span&gt;&lt;span style="font-size: 8pt; font-family: 'Courier New'"&gt;{&lt;br /&gt;&lt;span style="font-size: 8pt; font-family: 'Courier New'"&gt;&lt;span style="color: blue"&gt;  string&lt;/span&gt; categoryId = Context.Items[&lt;span style="color: #a31515"&gt;"category"&lt;/span&gt;].ToString();&lt;/span&gt;&lt;br /&gt;  &lt;/span&gt;&lt;span style="font-size: 8pt; font-family: 'Courier New'"&gt;&lt;span style="color: blue"&gt;string&lt;/span&gt; ItemId = Context.Items[&lt;span style="color: #a31515"&gt;"id"&lt;/span&gt;].ToString();&lt;br /&gt;  ...&lt;br /&gt;&lt;/span&gt;&lt;span style="font-size: 8pt; font-family: 'Courier New'"&gt;}&lt;/span&gt;&lt;span lang="EN-US" style="font-size: 9pt; color: #000066; font-family: 'Courier New'; mso-ansi-language: en-us"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt; &lt;p&gt;&lt;br /&gt;(*) Il routing non effettua un rewriting dell'URL vero e proprio, bensì costituisce un meccanismo 'bidirezionale' di generazione di URL.&lt;br /&gt;&lt;br /&gt;Technorati tags: &lt;a href="http://technorati.com/tag/ASP.NET"&gt;&lt;img alt=" " src="http://static.technorati.com/static/img/pub/icon-utag-16x13.png?tag=ASP.NET" /&gt;ASP.NET&lt;/a&gt; &lt;a href="http://technorati.com/tag/MVC"&gt;&lt;img alt=" " src="http://static.technorati.com/static/img/pub/icon-utag-16x13.png?tag=MVC" /&gt;MVC&lt;/a&gt;&lt;/p&gt;&lt;img src="http://blogs.ugidotnet.org:443/dsantarelli/aggbug/92495.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Dario Santarelli</dc:creator>
            <guid>http://blogs.ugidotnet.org:443/dsantarelli/archive/2008/05/03/asp.net-routing-e-webforms-tradizionali.aspx</guid>
            <pubDate>Sat, 03 May 2008 13:58:22 GMT</pubDate>
            <comments>http://blogs.ugidotnet.org:443/dsantarelli/archive/2008/05/03/asp.net-routing-e-webforms-tradizionali.aspx#feedback</comments>
            <slash:comments>2</slash:comments>
            <wfw:commentRss>http://blogs.ugidotnet.org:443/dsantarelli/comments/commentRss/92495.aspx</wfw:commentRss>
            <trackback:ping>http://blogs.ugidotnet.org:443/dsantarelli/services/trackbacks/92495.aspx</trackback:ping>
        </item>
        <item>
            <title>LinqDataSource e LINQ to SQL: Select, Insert, Update, Delete</title>
            <link>http://blogs.ugidotnet.org:443/dsantarelli/archive/2008/01/30/linqdatasource-e-linq-to-sql-select-insert-update-delete.aspx</link>
            <description>&lt;p&gt;Ci sono diversi dettagli a cui dobbiamo fare attenzione quando utilizziamo il behaviour di default del controllo &lt;a target="_blank" href="http://msdn2.microsoft.com/en-us/library/bb547113.aspx"&gt;LinqDataSource&lt;/a&gt; per quanto riguarda le classiche operazioni di Select, Insert, Update, Delete verso un model layer basato su un mapping con tabelle di un database. Infatti, se da una parte questo nuovo controllo rende ancora più immediato ed intuitivo l'accesso al modello dei dati, dall'altra rischia di autogenerare statement SQL spesso non accettabili da un punto di vista di performance, o comunque non sufficientemente ottimizzati per i nostri fini. Riporto quindi alcuni "fatti" da tener presente quando si sfruttano i meccanismi di autogenerazione di query SQL tramite LinqDataSource:&lt;/p&gt;
&lt;ul&gt;
    &lt;li&gt;(Ovvio) Qualora non specifichiamo esplicitamente la proprietà &lt;a target="_blank" href="http://msdn2.microsoft.com/en-us/library/system.web.ui.webcontrols.linqdatasource.select.aspx"&gt;Select&lt;/a&gt;, vengono estratte tutte le proprietà (o Data Columns se vogliamo) del nostro data object corrispondente al TableName specificato (Tabella &lt;em&gt;Customers&lt;/em&gt; nell'esempio). &lt;br /&gt;
    &lt;p class="MsoNormal" style="MARGIN-BOTTOM: 0pt; LINE-HEIGHT: normal; mso-pagination: none; mso-layout-grid-align: none"&gt;&lt;span style="FONT-SIZE: 8pt; COLOR: blue; FONT-FAMILY: 'Courier New'"&gt;&lt;br /&gt;
    &amp;lt;&lt;/span&gt;&lt;span style="FONT-SIZE: 8pt; COLOR: #a31515; FONT-FAMILY: 'Courier New'"&gt;asp&lt;/span&gt;&lt;span style="FONT-SIZE: 8pt; COLOR: blue; FONT-FAMILY: 'Courier New'"&gt;:&lt;/span&gt;&lt;span style="FONT-SIZE: 8pt; COLOR: #a31515; FONT-FAMILY: 'Courier New'"&gt;LinqDataSource&lt;/span&gt;&lt;span style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'"&gt; &lt;span style="COLOR: red"&gt;ID&lt;/span&gt;&lt;span style="COLOR: blue"&gt;="MyLinqDataSource"&lt;/span&gt; &lt;span style="COLOR: red"&gt;runat&lt;/span&gt;&lt;span style="COLOR: blue"&gt;="server"&lt;/span&gt; &lt;br /&gt;
                        &lt;/span&gt;&lt;span style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'"&gt;&lt;span style="COLOR: red"&gt;ContextTypeName&lt;/span&gt;&lt;span style="COLOR: blue"&gt;="MyDataContext"&lt;/span&gt; &lt;/span&gt;&lt;span style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'"&gt;&lt;span style="COLOR: red"&gt;TableName&lt;/span&gt;&lt;span style="COLOR: blue"&gt;="Customers"&lt;/span&gt; &lt;/span&gt;&lt;span style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'"&gt;&lt;span style="mso-spacerun: yes"&gt;      &lt;br /&gt;
    &lt;/span&gt;&lt;span style="COLOR: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;asp&lt;/span&gt;&lt;span style="COLOR: blue"&gt;:&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;LinqDataSource&lt;/span&gt;&lt;span style="COLOR: blue"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
    &lt;br /&gt;
    In pratica, in questi casi lo statement SQL autogenerato interesserà tutti i campi oggetto di un mapping diretto sulla tabella &lt;em&gt;Customers&lt;/em&gt; del DB. &lt;/p&gt;
    &lt;/li&gt;
    &lt;li&gt;La proprietà Select permette di reperire un sottoinsieme di proprietà del nostro data object, il che significa applicare una projection a runtime su un nuovo Anonymous Type 'bindabile' ad un controllo di presentazione dati (es. ListView). Ad esempio, &lt;br /&gt;
    &lt;br /&gt;
    &lt;span style="FONT-SIZE: 8pt; COLOR: blue; FONT-FAMILY: 'Courier New'"&gt;&amp;lt;&lt;/span&gt;&lt;span style="FONT-SIZE: 8pt; COLOR: #a31515; FONT-FAMILY: 'Courier New'"&gt;asp&lt;/span&gt;&lt;span style="FONT-SIZE: 8pt; COLOR: blue; FONT-FAMILY: 'Courier New'"&gt;:&lt;/span&gt;&lt;span style="FONT-SIZE: 8pt; COLOR: #a31515; FONT-FAMILY: 'Courier New'"&gt;LinqDataSource&lt;/span&gt;&lt;span style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'"&gt; ...&lt;/span&gt;&lt;span style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'"&gt;&lt;span style="mso-spacerun: yes"&gt;&lt;span style="FONT-SIZE: 8pt; COLOR: red; LINE-HEIGHT: 115%; FONT-FAMILY: 'Courier New'; mso-ansi-language: it; mso-fareast-font-family: 'Times New Roman'; mso-fareast-theme-font: minor-fareast; mso-fareast-language: it; mso-bidi-language: ar-sa"&gt; Select&lt;/span&gt;&lt;span style="FONT-SIZE: 8pt; COLOR: blue; LINE-HEIGHT: 115%; FONT-FAMILY: 'Courier New'; mso-ansi-language: it; mso-fareast-font-family: 'Times New Roman'; mso-fareast-theme-font: minor-fareast; mso-fareast-language: it; mso-bidi-language: ar-sa"&gt;="new(ID,FirstName,LN as LastName)" &lt;span style="FONT-SIZE: 8pt; FONT-FAMILY: 'Courier New'"&gt;&lt;span style="COLOR: red"&gt;TableName&lt;/span&gt;&lt;span style="COLOR: blue"&gt;="Customers"&lt;/span&gt; &lt;/span&gt;...&lt;/span&gt; &lt;/span&gt;&lt;span style="COLOR: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;asp&lt;/span&gt;&lt;span style="COLOR: blue"&gt;:&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;LinqDataSource&lt;/span&gt;&lt;span style="COLOR: blue"&gt;&amp;gt;&lt;br /&gt;
    &lt;br /&gt;
    &lt;/span&gt;&lt;/span&gt;potrebbe risultare molto più consigliabile dal momento che rispecchia la buona prassi di estrarre dalla nostra sorgente dati solo e soltanto i campi necessari, evitando dunque costi computazionali inutili da parte dello statement SQL autogenerato, che in questo particolare esempio interrogherà soltanto i campi ID,FirstName e LN della tabella &lt;em&gt;Customers&lt;/em&gt; oggetto del mapping &lt;/li&gt;
    &lt;li&gt;La combinazione delle proprietà Select e &lt;a target="_blank" href="http://msdn2.microsoft.com/en-us/library/bb550442.aspx"&gt;GroupBy&lt;/a&gt; permette di &lt;a target="_blank" href="http://msdn2.microsoft.com/en-us/library/bb470251.aspx"&gt;raggruppare ed aggregare dati&lt;/a&gt; su una o più colonne, facendoci poi perdere la possibilità di effettuare insert, update e delete sui dati che stiamo visualizzando &lt;/li&gt;
    &lt;li&gt;Per abilitare la modifica automatica dei dati dobbiamo impostare a true almeno una delle proprietà &lt;a target="_blank" href="http://msdn2.microsoft.com/en-us/library/bb516070.aspx"&gt;EnableUpdate&lt;/a&gt;/&lt;a target="_blank" href="http://msdn2.microsoft.com/en-us/library/bb550461.aspx"&gt;EnableInsert&lt;/a&gt;/&lt;a target="_blank" href="http://msdn2.microsoft.com/en-us/library/bb516540.aspx"&gt;EnableDelete&lt;/a&gt; (di default impostate a false), ma ciò ci vincola a &lt;strong&gt;non impostare&lt;/strong&gt; la proprietà Select (pena Exception). In questo modo però lo statement SQL autogenerato interrogherà tutti i campi della tabella in mapping con il data object (che verranno memorizzati nel ViewState). Ad esempio, nel caso dell'Update di un record, lo statement SQL autogenerato dal nostro LinqDataSource includerà nella clausola SET solo i campi che hanno subito una variazione reale, mentre nella clausola WHERE tutti i confronti sui campi con i valori precedenti alla modifica. &lt;/li&gt;
    &lt;li&gt;Negli scenari di insert/update/delete automatica dei record dobbiamo aver cura di fornire l'opportuna interfaccia utente che si occupi tra l'altro della visualizzazione dei campi di interesse:  ad esempio, in un GridView associato ad un LinqDataSource con &lt;em&gt;EnableUpdate/EnableInsert/EnableDelete = "true"&lt;/em&gt; (quindi privo di &lt;em&gt;Select&lt;/em&gt;/&lt;em&gt;GroupBy&lt;/em&gt;) potremmo impostare &lt;em&gt;AutoGenerateColumns="false"&lt;/em&gt; e dichiarare esplicitamente le Column da renderizzare.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;br /&gt;
Technorati tags: &lt;a href="http://technorati.com/tag/LinqDataSource"&gt;&lt;img alt=" " src="http://static.technorati.com/static/img/pub/icon-utag-16x13.png?tag=LinqDataSource" /&gt;LinqDataSource&lt;/a&gt; , &lt;a href="http://technorati.com/tag/LINQ"&gt;&lt;img alt=" " src="http://static.technorati.com/static/img/pub/icon-utag-16x13.png?tag=LINQ" /&gt;Linq&lt;/a&gt;&lt;/p&gt;&lt;img src="http://blogs.ugidotnet.org:443/dsantarelli/aggbug/90923.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Dario Santarelli</dc:creator>
            <guid>http://blogs.ugidotnet.org:443/dsantarelli/archive/2008/01/30/linqdatasource-e-linq-to-sql-select-insert-update-delete.aspx</guid>
            <pubDate>Wed, 30 Jan 2008 01:14:17 GMT</pubDate>
            <comments>http://blogs.ugidotnet.org:443/dsantarelli/archive/2008/01/30/linqdatasource-e-linq-to-sql-select-insert-update-delete.aspx#feedback</comments>
            <wfw:commentRss>http://blogs.ugidotnet.org:443/dsantarelli/comments/commentRss/90923.aspx</wfw:commentRss>
            <trackback:ping>http://blogs.ugidotnet.org:443/dsantarelli/services/trackbacks/90923.aspx</trackback:ping>
        </item>
        <item>
            <title>ASP.NET 3.5 Extensions Preview: occhio al designer nelle applicazioni MVC!</title>
            <link>http://blogs.ugidotnet.org:443/dsantarelli/archive/2007/12/25/asp.net-3.5-extensions-preview-occhio-al-designer-nelle-applicazioni-mvc.aspx</link>
            <description>&lt;p&gt;Oggi mentre stavo studiando il supporto MVC nell'ultima release delle &lt;a href="http://www.asp.net/downloads/3.5-extensions/" target="_blank"&gt;ASP.NET 3.5 Extensions Preview&lt;/a&gt; mi sono subito accorto del fatto che, creando una &lt;em&gt;MVC View Page&lt;/em&gt;/&lt;em&gt;Content Page,&lt;/em&gt; il template di default non genera automaticamente il file &amp;lt;page&amp;gt;.designer.cs/.vb. &lt;br /&gt;Questo inconveniente si risolve semplicemente facendo tasto destro sul file all'interno del Solution Explorer e selezionando "&lt;strong&gt;Convert to Web Application&lt;/strong&gt;".&lt;br /&gt;Ma guarda tu ;)...&lt;br /&gt;&lt;br /&gt;&lt;img src="http://img524.imageshack.us/img524/8707/swals2.jpg" /&gt;&lt;br /&gt;&lt;br /&gt;P.S.: e anche se in clamoroso ritardo... &lt;strong&gt;TANTI AUGURI DI BUON NATALE E FELICE ANNO NUOVO A TUTTI VOI&lt;/strong&gt; !!!&lt;br /&gt;&lt;br /&gt;&lt;img src="http://www.tnl.net/img/technorati.gif" /&gt; Technorati tags: &lt;a href="http://technorati.com/tag/ASP.NET%203.5"&gt;&lt;img alt=" " src="http://static.technorati.com/static/img/pub/icon-utag-16x13.png?tag=ASP.NET%203.5" /&gt;ASP.NET 3.5&lt;/a&gt; , &lt;a href="http://technorati.com/tag/MVC"&gt;&lt;img alt=" " src="http://static.technorati.com/static/img/pub/icon-utag-16x13.png?tag=MVC" /&gt;MVC&lt;/a&gt;&lt;/p&gt;&lt;img src="http://blogs.ugidotnet.org:443/dsantarelli/aggbug/90446.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Dario Santarelli</dc:creator>
            <guid>http://blogs.ugidotnet.org:443/dsantarelli/archive/2007/12/25/asp.net-3.5-extensions-preview-occhio-al-designer-nelle-applicazioni-mvc.aspx</guid>
            <pubDate>Tue, 25 Dec 2007 15:23:58 GMT</pubDate>
            <comments>http://blogs.ugidotnet.org:443/dsantarelli/archive/2007/12/25/asp.net-3.5-extensions-preview-occhio-al-designer-nelle-applicazioni-mvc.aspx#feedback</comments>
            <slash:comments>1</slash:comments>
            <wfw:commentRss>http://blogs.ugidotnet.org:443/dsantarelli/comments/commentRss/90446.aspx</wfw:commentRss>
            <trackback:ping>http://blogs.ugidotnet.org:443/dsantarelli/services/trackbacks/90446.aspx</trackback:ping>
        </item>
        <item>
            <title>ASP.NET Futures: il controllo History</title>
            <link>http://blogs.ugidotnet.org:443/dsantarelli/archive/2007/09/10/asp.net-futures-il-controllo-history.aspx</link>
            <description>&lt;p&gt;Un classico problema delle applicazioni AJAX è mantenere la consistenza della navigazione quando si utilizzano i controlli ("Avanti" e "Indietro") del browser. Chi sviluppa applicazioni Web AJAX-enabled, sicuramente si è accorto di come spesso l'utilizzo del pulsante "Indietro" del browser ad esempio possa provocare una navigazione verso un contenuto o una pagina non desiderata. Il problema è ancor più evidente se vengono generati diversi postback asincroni all'interno della stessa pagina.&lt;br /&gt;
Ebbene, se precedentemente dovevamo trovare soluzioni ad hoc più o meno eleganti a questo tipo di anomalia funzionale, ora abbiamo il controllo History, che rende la programmabilità della navigazione logica delle nostre applicazioni AJAX-enabled molto più naturale ed intuitiva.&lt;br /&gt;
Questo server control (attualmente nel namespace Microsoft.Web.Preview.UI.Controls) ha infatti lo scopo di permettere la gestione lato server delle informazioni di stato riguardanti la navigazione (chiamate "history point"), che possono dunque essere sfruttate per ricreare il contenuto corretto della pagina ad ogni interazione dell'utente con il  browser. E' inoltre degno di nota l'interfacciamento con l' history-stack del browser: ce ne accorgiamo dando una rapida occhiata al javascript che il controllo genera in fase di rendering ;). &lt;br /&gt;
Nello specifico, il funzionamento del controllo prevede che l'invio di ciascuna richiesta di navigazione scateni l'evento &lt;em&gt;Navigate&lt;/em&gt;, all'interno del quale possiamo controllare sia URL che history points, al fine di rendere semplice la ricostruzione dello stato "cronologicamente" corretto della nostra pagina.&lt;br /&gt;
Il suo utilizzo è veramente banale: supponiamo che nel nostro UpdatePanel sia inserito un Button che genera un AsyncPostback, tramite cui possiamo aggiungere un nuovo "history point". Nella nostra pagina basterà inserire il seguente markup:&lt;/p&gt;
&lt;div class="wlWriterSmartContent" id="57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:273ca9b7-5f94-4ca1-bbab-2ae78cd0dc25" contenteditable="false" style="PADDING-RIGHT: 0px; DISPLAY: inline; PADDING-LEFT: 0px; FLOAT: none; PADDING-BOTTOM: 0px; MARGIN: 0px; PADDING-TOP: 0px"&gt;
&lt;pre style="OVERFLOW: auto; BACKGROUND-COLOR: white"&gt;&lt;div&gt;&lt;!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--&gt;&lt;span style="COLOR: #000000"&gt;...
&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: #800000"&gt;asp:History &lt;/span&gt;&lt;span style="COLOR: #ff0000"&gt;runat&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;="server"&lt;/span&gt;&lt;span style="COLOR: #ff0000"&gt; ID&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;="PageHistory1"&lt;/span&gt;&lt;span style="COLOR: #ff0000"&gt; OnNavigate&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;="OnNavigateEvent"&lt;/span&gt;&lt;span style="COLOR: #ff0000"&gt; &lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;
&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: #800000"&gt;asp:Button &lt;/span&gt;&lt;span style="COLOR: #ff0000"&gt;ID&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;="TestButt"&lt;/span&gt;&lt;span style="COLOR: #ff0000"&gt; runat&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;="server"&lt;/span&gt;&lt;span style="COLOR: #ff0000"&gt; Text&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;="Aggiungi nuovo HistoryPoint"&lt;/span&gt;&lt;span style="COLOR: #ff0000"&gt; OnClick&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;="MyButtonClick"&lt;/span&gt;&lt;span style="COLOR: #ff0000"&gt; &lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;
...&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;
&lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
mentre nel codebehind...&lt;br /&gt;
&lt;br /&gt;
&lt;div class="wlWriterSmartContent" id="57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:dcc25300-f56c-4ddf-9736-2251e359f58c" contenteditable="false" style="PADDING-RIGHT: 0px; DISPLAY: inline; PADDING-LEFT: 0px; FLOAT: none; PADDING-BOTTOM: 0px; MARGIN: 0px; PADDING-TOP: 0px"&gt;
&lt;pre style="OVERFLOW: auto; BACKGROUND-COLOR: white"&gt;&lt;div&gt;&lt;!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--&gt;&lt;span style="COLOR: #0000ff"&gt;public&lt;/span&gt;&lt;span style="COLOR: #000000"&gt; &lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;void&lt;/span&gt;&lt;span style="COLOR: #000000"&gt; OnNavigateEvent(&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;object&lt;/span&gt;&lt;span style="COLOR: #000000"&gt; sender, HistoryEventArgs args)
{
    &lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;if&lt;/span&gt;&lt;span style="COLOR: #000000"&gt; (args.State[&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;"&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;MyState&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;"&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;] &lt;/span&gt;&lt;span style="COLOR: #000000"&gt;!=&lt;/span&gt;&lt;span style="COLOR: #000000"&gt; &lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;null&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;)
    {
      &lt;/span&gt;&lt;span style="COLOR: #008000"&gt;//&lt;/span&gt;&lt;span style="COLOR: #008000"&gt; viene recuperato lo stato per la corretta ricostruzione
      &lt;/span&gt;&lt;span style="COLOR: #008000"&gt;//&lt;/span&gt;&lt;span style="COLOR: #008000"&gt; del contenuto della pagina&lt;/span&gt;&lt;span style="COLOR: #008000"&gt;
&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;      &lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;string&lt;/span&gt;&lt;span style="COLOR: #000000"&gt; pageStateValue &lt;/span&gt;&lt;span style="COLOR: #000000"&gt;=&lt;/span&gt;&lt;span style="COLOR: #000000"&gt; args.State[&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;"&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;MyState&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;"&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;].ToString();         
    }
}

&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;public&lt;/span&gt;&lt;span style="COLOR: #000000"&gt; &lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;void&lt;/span&gt;&lt;span style="COLOR: #000000"&gt; MyButtonClick(&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;object&lt;/span&gt;&lt;span style="COLOR: #000000"&gt; sender, EventArgs args)
{
  &lt;/span&gt;&lt;span style="COLOR: #008000"&gt;//&lt;/span&gt;&lt;span style="COLOR: #008000"&gt; Aggiunta di un nuovo HistoryPoint...&lt;/span&gt;&lt;span style="COLOR: #008000"&gt;
&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;  PageHistory1.AddHistoryPoint(&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;"&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;MyState&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;"&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;, &lt;/span&gt;&lt;span style="COLOR: #000000"&gt;"&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;myData....&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;"&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;);
}&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;
&lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
Notiamo immediatamente come tutto ruoti intorno all'oggetto State (che è di tipo Dictionary&amp;lt;string,object&amp;gt;), in cui possiamo inserire i nostri HistoryPoint organizzandoli eventualmente per categoria (in base alle key che impostiamo nel Dictionary). &lt;br /&gt;
Un' ultima ma fondamentale considerazione riguarda la sicurezza: nonostante ogni informazione di stato possa essere codificata e/o criptata, il controllo History (come il ViewState) va considerato come un qualunque controllo sfruttabile per inviare dati 'maliziosi' al server, quindi potenzialmente non sicuro. Insomma, finché possibile, meglio evitare la memorizzazione di dati sensibili nei nostri HistoryPoint!!!&lt;br /&gt;
&lt;br /&gt;
&lt;img alt="" src="http://www.tnl.net/img/technorati.gif" /&gt;  Technorati tags: &lt;a rel="tag" href="http://technorati.com/tag/ASP.NET"&gt;&lt;img style="BORDER-TOP-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; MARGIN-LEFT: 0.4em; VERTICAL-ALIGN: middle; BORDER-RIGHT-WIDTH: 0px" alt="*" src="http://static.technorati.com/static/img/pub/icon-utag-16x13.png?tag=ASP.NET" /&gt;ASP.NET&lt;/a&gt;, &lt;a rel="tag" href="http://technorati.com/tag/RSS"&gt;&lt;img style="BORDER-TOP-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; MARGIN-LEFT: 0.4em; VERTICAL-ALIGN: middle; BORDER-RIGHT-WIDTH: 0px" alt="*" src="http://static.technorati.com/static/img/pub/icon-utag-16x13.png?tag=Ajax" /&gt;Ajax&lt;/a&gt;&lt;img src="http://blogs.ugidotnet.org:443/dsantarelli/aggbug/88204.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Dario Santarelli</dc:creator>
            <guid>http://blogs.ugidotnet.org:443/dsantarelli/archive/2007/09/10/asp.net-futures-il-controllo-history.aspx</guid>
            <pubDate>Mon, 10 Sep 2007 01:04:28 GMT</pubDate>
            <comments>http://blogs.ugidotnet.org:443/dsantarelli/archive/2007/09/10/asp.net-futures-il-controllo-history.aspx#feedback</comments>
            <wfw:commentRss>http://blogs.ugidotnet.org:443/dsantarelli/comments/commentRss/88204.aspx</wfw:commentRss>
            <trackback:ping>http://blogs.ugidotnet.org:443/dsantarelli/services/trackbacks/88204.aspx</trackback:ping>
        </item>
    </channel>
</rss>