Roberto Brunetti

Developing in the cloud

.NET Programming

ASP.NET 3.5: insomma, quali sono le novità ? What's new

Andando a spasso su internet si trovano migliaia di post incrociati, rediretti e "rimbalzanti" l'uno con l'altro sulle novità del Framework 3.5. Quello che non ho trovato è un elenco dettagliato che vada oltre quanto già citato nell'ampia documentazione.

In questi giorni di raffreddore (per questo vado a spasso su internet e non nel bosco vicino casa mia :-)) ho messo mano ad un progetto ASP.NET 2.0 per vedere le reali implicazioni di migrazione verso la versione RTM ormai alle porte. Ovviamente il post non vuole essere completo di TUTTE le modifiche/novità.

Per prima cosa occorre mettere qualche puntino sulle "i". Spesso alcuni prodotti/tecnologie vengono indicate come novità della 3.5, mentre sono prodotti esistenti già in versione 2.0 o 3.0 che hanno ricevuto aggiunte/improvment nella 3.5

Non sono novità della 3.5:

1) Windows Workflow Foundation: già presente nella versione 3.0. Il prodotto/tecnologie esiste già da un anno (e personalmente lo trovo eccezionale !!!).
Ci sono alcune aggiunte come WorkflowRuntimeBehavior (e classi correlate) per ospitare workflow in WCF. La versione delle lilbrerie (almeno fino ad adesso) core di WF restano quindi in versione 3.0 e ad essa si aggiunge la System.WorkflowService in versione 3.5

2) Windows Presentation Foundation: già presente nella versione 3.0. Il prodotto/tecnologie esiste già da un anno. Non sono io la persona di riferimento (è Luca Regnicoli che si occupa di WPF nel nostro gruppo), quindi aggiungo solo che le varie dll restano in versione 3.0 tranne la System.Windows.Presentation

3) Windows Communication Foundation: già presente nella versione 3.0. Paolo nel suo blog ha già introdotto le novità

4) Windows CardSpace: già presente nella versione 3.0 e poco citato nei vari post/forum sulla versione 3.5

5) ASP.NET AJAX: già presente da circa 1 anno come libreria aggiuntiva System.Web.Extension in versione 1.0.61025.0 e come Add-in per Visual Studio 2005. Ci sono alcune novità di cui parliamo più avanti e non solo per AJAX all'interno della versione 3.5 di questa libreria.

La precisazione era dovuta solo per fare chiarezza e soprattutto per trovare meglio documentazione sui prodotti.

Vendiamo alle Novità di ASP.NET 3.5

Portando un progetto AJAX sotto Visual Studio 2008 il Conversion Wizard esegue alcune modifiche web.config. Innanzi tutto viene richiesto se portare il progetto alla versione 3.5 e, ovviamente rispondendo "Yes" troviamo queste aggiunte:

    <system.web>
        <compilation debug="false">

          <assemblies>
            <add assembly="System.Core, Version=3.5.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/>
            <add assembly="System.Data.DataSetExtensions, Version=2.0.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/>
            <add assembly="System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
            <add assembly="System.Xml.Linq, Version=3.5.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/>
          </assemblies>

        </compilation>


Vengono quindi aggiunte alcune delle librerie comuni della versione 3.5. In un web.config di una applicazione ASP.NET AJAX 1.0 veniva solo aggiunta la System.Web.Extension nella versione indicata prima.

Sempre nella sezione <system.web> vengono aggiunti/modificati

      <pages>
        <controls>
          <add tagPrefix="asp" namespace="System.Web.UI" assembly="System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
          <add tagPrefix="asp" namespace="System.Web.UI.WebControls" assembly="System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
        </controls>
      </pages>


La prima riga era presente anche nei progetti ASP.NET AJAX 1.0 (con la versione 1.0.61025.0) e consente di utilizzare il namespace asp: per i 4 controlli AJAX (ScriptManager, Timer, UpdatePanel, UpdateProgress) e le interfacce IScriptControl e IExtenderControl, nonchè il controllo base ExtenderControl.

La seconda riga, strana a prima vista, aggiunge il prefisso asp anche per i controlli presenti sotto System.Web.UI.WebControls della System.Web.Extensions.dll: i nuovi controlli ASP.NET sono stati inseriti in questa librerie e non nella classica System.Web.dll.

Nella sezione <system.codedom> viene invece configurato il compilatore C# 3.5 (o VB nel caso di progetti VB):

    <system.codedom>
      <compilers>
        <compiler language="c#;cs;csharp" extension=".cs" compilerOptions="/warnaserror-" warningLevel="4"
                  type="Microsoft.CSharp.CSharpCodeProvider, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
          <providerOption name="CompilerVersion" value="v3.5"/>
        </compiler>
     </compilers>
    </system.codedom>
 

come si nota providerOption viene impostato alla 3.5. Occorre ricordarsi ovviamente di verificare che in IIS l'applicazione sia associata a ASP.NET versione ?....2.0 ! Già, perchè, contrariamente a quanto si pensa (almeno fino alla RC di .NET FW 3.5) il motore di ASP.NET resta alla versione 2.0, potendo però usare i compilatori della 3.5 e le librerie della 3.5. L'architettura di ASP.NET, sin dalla versione 1.0, consente aggiunte di questo tipo. Quindi l'aggancio fra IIS e ASP.NET viene sempre fatto per le varie estensioni a c:\windows\microsoft.net\framework\v2.0.50727\aspnet_isapi.dll.

La sezione <configSections> resta praticamente inalterata. Questa la versione con ASP.NET AJAX 1.0:

 <configSections>
  <sectionGroup name="system.web.extensions" type="System.Web.Configuration.SystemWebExtensionsSectionGroup, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35">
   <sectionGroup name="scripting" type="System.Web.Configuration.ScriptingSectionGroup, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35">
    <section name="scriptResourceHandler" type="System.Web.Configuration.ScriptingScriptResourceHandlerSection, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" requirePermission="false" allowDefinition="MachineToApplication"/>
    <sectionGroup name="webServices" type="System.Web.Configuration.ScriptingWebServicesSectionGroup, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35">
     <section name="jsonSerialization" type="System.Web.Configuration.ScriptingJsonSerializationSection, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" requirePermission="false" allowDefinition="Everywhere"/>
     <section name="profileService" type="System.Web.Configuration.ScriptingProfileServiceSection, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" requirePermission="false" allowDefinition="MachineToApplication"/>
     <section name="authenticationService" type="System.Web.Configuration.ScriptingAuthenticationServiceSection, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" requirePermission="false" allowDefinition="MachineToApplication"/>
    </sectionGroup>
   </sectionGroup>
  </sectionGroup>
 </configSections>

Questa la versione della versione 3.5:

 <configSections>
  <sectionGroup name="system.web.extensions" type="System.Web.Configuration.SystemWebExtensionsSectionGroup, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">
   <sectionGroup name="scripting" type="System.Web.Configuration.ScriptingSectionGroup, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">
    <section name="scriptResourceHandler" type="System.Web.Configuration.ScriptingScriptResourceHandlerSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="MachineToApplication"/>
    <sectionGroup name="webServices" type="System.Web.Configuration.ScriptingWebServicesSectionGroup, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">
     <section name="jsonSerialization" type="System.Web.Configuration.ScriptingJsonSerializationSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="Everywhere"/>
     <section name="profileService" type="System.Web.Configuration.ScriptingProfileServiceSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="MachineToApplication"/>
     <section name="authenticationService" type="System.Web.Configuration.ScriptingAuthenticationServiceSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="MachineToApplication"/>
     <section name="roleService" type="System.Web.Configuration.ScriptingRoleServiceSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="MachineToApplication"/></sectionGroup>
   </sectionGroup>
  </sectionGroup>
 </configSections>

Quesito da Settimana Egninistica: trovate le differenze :-)

L'unica differenza, a parte la già citata versione della System.Web.Extensions è rappresentata dall'aggiunta del roleService: in pratica nella nuova versione viene esposto anche RoleManager (oltre a autenticazione e Profile già presenti nella precedente versione) alla libreria client di AJAX; si può interrogare anche l'appartenza a ruoli con una richiesta tramite i proxy lato client.

Anche le sezioni <httpHandler> e <httpModules> si aggiornano alla nuova versione della dll.

  <httpHandlers>
   <remove verb="*" path="*.asmx"/>
   <add verb="*" path="*.asmx" validate="false" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
   <add verb="*" path="*_AppService.axd" validate="false" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
   <add verb="GET,HEAD" path="ScriptResource.axd" type="System.Web.Handlers.ScriptResourceHandler, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" validate="false"/>
  </httpHandlers>
  <httpModules>
   <add name="ScriptModule" type="System.Web.Handlers.ScriptModule, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
  </httpModules>


Così come la sezione <handler> e <module>, già prevista nella versione 1.0 di ASP.NET AJAX per l'integrazione della pipeline con IIS7:

 <system.webServer>
  <validation validateIntegratedModeConfiguration="false"/>
  <modules>
   <add name="ScriptModule" preCondition="integratedMode" type="System.Web.Handlers.ScriptModule, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
  </modules>
  <handlers>
   <remove name="WebServiceHandlerFactory-Integrated"/>
   <add name="ScriptHandlerFactory" verb="*" path="*.asmx" preCondition="integratedMode" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
   <add name="ScriptHandlerFactoryAppServices" verb="*" path="*_AppService.axd" preCondition="integratedMode" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
   <add name="ScriptResource" preCondition="integratedMode" verb="GET,HEAD" path="ScriptResource.axd" type="System.Web.Handlers.ScriptResourceHandler, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
  </handlers>
 </system.webServer>

A proposito di interazione/integrazione con IIS ricordo due cose:

1) Occhio al validateIntegratedModeConfiguration="false": questo flag indica a IIS 7 di non eseguire un controllo sulla configurazione di ASP.NET (già dalla versione 2.0) prima di eseguire l'applicazione in modalità integrata. In questo modo, giustamente, vengono saltati i controlli visto che il web.config AJAX è corretto per girare in IIS. Occhio solamente alle altre parti di configurazione custom che inseriamo nel config.

2) Contrariamente a quanto ho letto spesso su vari blog italiani e non, NON E' una novità della versione 3.5 l'integrazione con la Pipeline di IIS. Tale integrazione è già garantita dalla versione 2.0 (tanto è vero che anche il runtime della 3.5 è quello della 2.0) e quindi è possibile proteggere risorse non ASP.NET (.asp, .php, .jsp o semplici immagini) con i meccanismi di autenticazione di ASP.NET: in pratica se l'applicazione ASP.NET viene fatta girare in IIS7 in un Application Pool marcato come "integrated" viene eseguite SEMPRE la pipeline di ASP.NET anche per risorse non ASP.NET.
Ricordo anche con IIS6 e ASP.NET 2.0 è possibile proteggere risorse non ASP.NET con i meccanismi di autenticazione e autorizzazione di ASP.NET 2.0: è sufficiente indicare nel Wildcard Mapping di IIS la solita dll ISAPI (ASPNET_ISAPI.dll) per eseguire la pipeline di ASP.NET 2.0 per poi far recuperare la risorsa da IIS: questa coppia di versioni (IIS6 e ASP.NET 2.0) è la prima che consente di proteggere anche contenuti dinamici (.asp, .php, .jsp etc) con l'autenticazione/autorizzazione di ASP.NET. Il meccanismo sfrutta una funzionalità "vecchia" di IIS che usa una estensione denominata  HSE_REQ_EXEC_URL che passa la palla a ASP.NET per l'esecuzione della pipeline; ASP.NET usa il DefaultHttpHandler che non fa nient'altro che ripassare la richiesta a IIS: se la risposta dell'autenticazione è positiva IIS processa la richiesta cercando, come se niente fosse successo, l'etensione ISAPI per eseguire la risorsa.
Per la precisione anche con ASP.NET 1.0 e IIS5 è possibile proteggere risorse, in questo caso però NON dinamiche (.gif, .jpg, .doc etc) tramite l'autenticazione di ASP.NET: in questo caso sarà lo StaticFileHandler di ASP.NET a prelevare la risorsa e per questo motivo non possono essere eseguite risorse dinamiche.

Questa filippica per sottilineare che ASP.NET 3.5 e IIS 7 non abbiano introdotto questa caratteristica: già le versioni precedenti erano dotate di questa interessante possibilità.

Visual Studio 2008 fornisce template per la creazione di AJAX Client Behavior, AJAX Client Library, AJAX Master Page, AJAX Web Form e AJAX WCF Service. Molte di queste cose si dovevano scrivere a mano: la nuova versione facilita il compito e standardizza un minino il modo con cui creare i sorgenti.

I nuovi controlli, che come abbiamo detto stanno sotto System.Web.Extensions, lasciando intatta e alla versione 2.0 la System.Web, sono

ListView
DataPager
LinqDataSource - vi rimando al libro Introducing Linq per una introduzione a LINQ. Il primo capitolo è disponibile sul sito ufficiale www.introducinglinq.com

Vi rimando alla documentazione su MSDN, più che esauriente su questi controlli.

E' disponibile uno strumento denominato aspnet_merge.exe che consente di unire assembly precompilati (tramite il noto aspnet_compiler della versione 2.0) per facilitare soprattutto l'aggiornamento di parti di codice dell'applicazione.

Comments

Roberto Brunetti Mobile Blog said:

Dopo aver installato VS 2008 side by side con VS 2005 sulla stessa macchina ho trovato alcune incongruenze

# novembre 24, 2007 1.05

Roberto Brunetti said:

Dopo aver installato VS 2008 side by side con VS 2005 sulla stessa macchina ho trovato alcune incongruenze

# novembre 24, 2007 1.06