back to top

Sviluppare in ASP.Net con Visual Studio

L’obiettivo della presente guida è quello di introdurvi alle applicazioni web sviluppate attraverso Microsoft ASP.NET, il famoso framework web della casa di Redmond usufruendo degli strumenti offerti da Visual Studio, l’ambiente di sviluppo di riferimento per gli sviluppatori .NET.

Il mondo del web offre diverse scelte per quanto riguarda gli ambienti di sviluppo e negli ultimi anni ASP.NET si è molto evoluto, fino a divenire uno dei framework per la gestione di richieste HTTP più consistenti, stabili e ricchi di funzionalità nel panorama mondiale.

ASP.NET e Visual Studio, il noto ambiente di sviluppo Microsoft, includono una grande quantità di funzionalità che rendono la vita degli sviluppatori web più facile. Per esempio Visual Studio mette a disposizione diversi modelli di progetto che è possibile utilizzare per sviluppare un sito ed inoltre supporta diverse modalità di distribuzione delle applicazioni web, come vedremo.

Attraverso il debugger di Visual Studio è possibile testare il sito e analizzare le aree critiche del nostro codice, al fine di individuare potenziali problemi. Attraverso il designer è possibile inoltre sviluppare interfacce utente avanzate in modo molto rapido e intuitivo, spostando tramite il mouse i controlli per visualizzare in tempo reale come essi appariranno nella versione definitiva dell’applicazione.

Utilizzando ASP.NET è dunque possibile creare qualsiasi cosa che è possibile trovare su internet, dai portali di e-commerce, ai siti di consultazione di dati, ai servizi web. Per utilizzare questo framework è però necessario imparare ad utilizzare Visual Studio, conoscere gli oggetti del .NET Framework e saper utilizzare un linguaggio di programmazione ad oggetti tra quelli messi a disposizione dal framework (nel nostro caso utilizzeremo C#).

ASP.NET è stato rilasciato per la prima volta nel Gennaio 2002 con la versione 1.0 del .NET Framework e presentato come successore della tecnologia Microsoft ASP (Active Server Pages). A differenza di quest’ultima tecnologia ASP.NET si basa, come tutte le applicazioni della famiglia Microsoft .NET, sul CLR (Common Language Runtime).

Il CLR consente agli sviluppatori di scrivere codice utilizzando uno qualunque dei linguaggi di alto livello supportati dal .NET Framework (C#, VB.NET, J#) ma anche altri linguaggi. Questo perchè il CLR aderisce agli standard ECMA (European Computer Manufacturers Association).

Il punto di forza delle applicazioni ASP.NET è che esse sono sensibilmente più performanti rispetto a quelle realizzate tramite linguaggi di programmazione interpretati grazie al fatto che il codice relativo viene precompilato in file gestiti dal server web.

L’obiettivo fondamentale di tutto ciò è quello di rendere lo sviluppo di applicazioni web più simile possibile allo sviluppo di applicazioni Windows. In ASP.NET infatti i controlli funzionano in modo similare ai corrispondenti controlli delle applicazioni Windows e, come quest’ultimi, consentono di gestire una grande varietà di eventi (si parla di modello event-driven). In pratica è ASP.NET che produce blocchi di codice HTML che vengono inseriti nella pagina che viene inviata al browser dell’utente finale, riproducendo il comportamento appropriato dei controlli.

Dopo il lancio della prima versione la tecnologia ASP.NET è stata ulteriormente migliorata e arricchita di nuove funzionalità ed è oggi arrivata alla versione 4.0, includendo nuove funzionalità che rappresentano la nuova frontiera dello sviluppo web moderno: LINQ, AJAX , Silverlight, WPF (Windows Presentation Foundation), WCF (Windows Communication Foundation) e WF (Windows Workflow Foundation).

Evoluzione delle applicazioni web

Come ben sappiamo Internet nacque come un esperimento volto a creare una rete permanente di informazioni e per tale motivo era rivolta fondamentalmente ad istituti accademici e governativi, con l’obiettivo di permettere ai ricercatori di tutto il mondo di condividere determinate informazioni.

La vera rivoluzione di Internet ebbe inizio con la creazione del primo browser HTML nel 1993. La prima generazione di siti web consisteva fondamentalmente in un insieme di pagine HTML statiche, aventi dunque un contenuto fisso che doveva essere aggiornato a mano da coloro che amministravano il sito stesso. Una pagina HTML consiste in un documento con un certo contenuto, formattato secondo opportune regole, che consentono la visualizzazione dello stesso sul nostro computer (attraverso un browser web).

Un documento HTML ha due tipi di contenuti che sono testi ed elementi (o tag) che indicano al browser di turno la formattazione da adottare. I tag sono facilmente riconoscibili, poichè sono delimitati dalle parentesi angolari (< >), Un esempio di codice HTML è il seguente

<html>
<head>
<title>Pagina web di prova</title>
</head>
<body>
<h1>Pagina web di prova</h1>
<p>Benvenuti in una pagina web di prova. </p>
</body>
</html>

Si tratta di una pagina che contiene un semplice titolo e una linea di testo e che in un browser verrà visualizzata nel modo seguente

Questa pagina non ha niente di interattivo, non richiede un server web e dunque non può essere considerata un’applicazione web. Per cominciare a parlare di applicazioni web dobbiamo arrivare alla versione 2.0 del linguaggio HTML che ha portato all’introduzione della tecnologia denominata HTML Form.

Questa tecnologia espande le funzionalità dell’HTML di base includendo non soltanto tag per la formattazione dei contenuti, ma anche tag per componenti grafici, corrispondenti ai controlli delle applicazioni windows form: dropdown, textbox, checkbox, radiobutton, ecc.

Ecco un esempio di questo tipo di codice

<html>
<head>
<title>Pagina web di prova</title>
</head>
<body>
<form>
<input type="checkbox" />
Scelta A<br />
<input type="checkbox" />
Scelta B<br /><br />
<input type="submit" value="Invia" />
</form>
</body>
</html>

e la relativa pagina web

In un form HTML tutti i controlli sono posti tra i tag <form> e </form>. Nell’esempio precedente i controlli sono due checkbox e un button (tipo submit). Questo tipo di tecnologia consente di creare pagine per l’input dei dati che consentono di inviare (ad esempio dopo il click del pulsante) tutti i dati inseriti ad un server web in un’unica stringa. Dal lato del server un’apposita applicazione riceve poi i dati e li elabora.

In pratica i controlli che oggi si utilizzano per le applicazioni web più avanzate sono gli stessi introdotti con l’HTML 2.0. La differenza è data dal tipo di applicazioni che girano sui server web. In passato infatti quando un utente cliccava sul pulsante di invio dei dati occorreva gestire tutti gli aspetti del trasferimento ad essi relativo, utilizzando ad esempio lo standard CGI (Common Gateway Interface). Oggi invece si occupa di tutto in modo molto più efficiente la piattaforma ASP.NET.

Per comprendere le motivazioni che hanno portato alla creazione di ASP.NET è necessario analizzare le problematiche legate alle prime tecnologie utilizzate nello sviluppo web. Con lo standard CGI originale, ad esempio, il server web deve lanciare una nuova istanza dell’applicazione ad ogni richiesta (programmazione lato server) e se il sito web in questione è molto popolare il server risente pesantemente del peso di migliaia di istanze aperte contemporaneamente. Inoltre l’utilizzo di questo tipo di tecnologie comporta che per avere a disposizione funzionalità di alto livello (come l’autenticazione o la consultazione di dati ottenuti da un database) occorre scrivere molto codice specifico, con il rischio di incorrere in errori di programmazione.

Proprio per evitare questi problemi Microsoft ha introdotto ASP.NET, una piattaforma di sviluppo di alto livello che permette ai programmatori di sviluppare pagine web dinamiche senza soffermarsi sui dettagli implementativi di basso livello. Tale piattaforma è stata sviluppata per fungere da framework per lo sviluppo di applicazioni web, fornendo migliori prestazioni e strumenti più avanzati rispetto alle tecnologie ad essa precedenti.

Accanto alla programmazione lato server si è andata affermando negli anni un altro tipo di programmazione, denominata lato client. In questo paradigma di programmazione vengono inserite nelle pagine applicazioni (create in JavaScript, ActiveX, Java o Flash per esempio) che non richiamano alcun processo lato server. In pratica le applicazioni vengono scaricate dal browser del client e vengono eseguite sulla macchina locale. Un problema di questo tipo di approccio è che le diverse tecnologie impiegate nello sviluppo di applicazioni possono non essere supportate allo stesso modo da tutti i sistemi operativi e browser. Per questo motivo i programmatori sono costretti a testare i propri siti web sui diversi sistemi esistenti.

La tecnologia ASP.NET è stata realizzata come tecnologia lato server. Infatti tutto il codice viene eseguito sul server e quando l’esecuzione termina l’utente riceve una pagina HTML ordinaria che può essere visualizzata in qualsiasi browser. Tuttavia la programmazione lato client non è stata completamente abbandonata. In alcuni casi infatti ASP.NET consente di combinare le caratteristiche positive di essa con le potenzialità della programmazione lato server.

Il .NET Framework

Il .NET Framework è fondamentalmente un insieme di diverse tecnologie:

  • Linguaggi .NET – Visual Basic, C#, JScript.NET, J# e C++
  • Common Language Runtime (CLR) – Il motore che esegue tutti i programmi .NET e fornisce servizi alle varie applicazioni (come gestione della memoria e ottimizzazione delle prestazioni)
  • .NET Framework Class Library – Libreria che contiene migliaia di funzionalità predefinite da utilizzare nelle nostre applicazioni
  • ASP.NET – Il motore che gestisce le applicazioni web create in .NET
  • Visual Studio – Ambiente di sviluppo che contiene di un ricco insieme di caratteristiche che favoriscono la produttività degli sviluppatori e semplificano il debugging delle applicazioni

Spesso la separazione tra queste componenti non è chiara e si tende a confondere le une con le altre. Di seguito un’ immagine tratta dal sito Microsoft che aiuta a comprendere meglio la suddivisione delle varie tecnologie all’interno della Class Library

I linguaggi più utilizzati sono sicuramente C# e VB.NET. In particolare C# è un linguaggio relativamente nuovo progettato per la versione 1.0 di .NET. I due linguaggi utilizzano una sintassi differente ma entrambi sfruttano le funzionalità della Class Library e sono supportati dal CLR.

Tutti i linguaggi .NET vengono compilati in un altro linguaggio di basso livello prima che il codice venga eseguito. Tale linguaggio è denominato Common Intermediate Language (CIL o semplicemente IL) e il CLR opera soltanto su questo tipo di codice. Le seguenti immagini tratte dal sito Microsoft illustrano come i linguaggi .NET vengano compilati in CIL e la struttura del CLR

Struttura del CLR

In pratica ogni file EXE (o DLL) generato tramite .NET contiene codice CIL e questi sono i file che vengono distribuiti sui pc client, nel caso di applicazioni windows form, o sui server web, nel caso di applicazioni web. Il CLR non ha idea di quale linguaggio sia stato utilizzato per generare il codice ed effettua un’altra compilazione per trasformare il codice CIL in linguaggio macchina. Questo passaggio avviene quando il codice viene eseguito.

Il protocollo HTTP (in ambiente .NET)

Il meccanismo con cui i diversi browser comunicano con i siti web, come accennato in precedenza, si basa su un protocollo denominato Hypertext Transfer Protocol (HTTP). Nella sua forma originale questo protocollo è stato progettato per il trasferimento di documenti ipertestuali, ovvero documenti legati insieme ma senza una interfaccia utente ben definita, quello che è invece il punto di forza delle moderne applicazioni web.

HTTP è un protocollo che si basa su alcuni comandi di base. I più importanti di essi sono GET e POST, ma altri importanti comandi sono ad esempio HEAD e PUT. Il metodo GET restituisce l’informazione identificata dall’ Uniform Resource Identifier (URI) specificato attraverso la richiesta (in pratica l’indirizzo del sito web). Il metodo POST serve ad inviare una richiesta al server web. Il comando HEAD restituisce solo le informazioni di testata identificate attraverso l’URI della richiesta. Anche il metodo PUT è utilizzato per inviare informazioni al server ma sotto forma di documenti e record anziché parametri.

L’obiettivo della presente lezione non è quello di approfondire la conoscenza di HTTP, ma quello di spiegare come esso sia radicato all’interno dell’ambiente di sviluppo .NET. Tale ambiente include infatti diverse classi che consentono di effettuare richieste HTTP. La classe WebRequest, ad esempio, include un metodo, denominato GetResponse, che consente di inviare una richiesta ad un indirizzo specifico.

Per vedere come effettuare una richiesta diretta ad un server web senza un browser implementiamo un piccolo programma d’esempio. Avviamo Visual Studio e creiamo un nuovo progetto, scegliendo nella finestra di dialogo New Project il tipo di progetto Console Application

Aggiungiamo ora al programma appena generato il codice necessario ad effettuare richieste web. Visual Studio crea come punto di avvio dell’applicazione un file denominato Program.cs.

All’interno di tale file aggiungiamo il seguente codice:

using System;using System.Collections.Generic; 
using System.Linq;
using System.Text;
using System.Net;
using System.IO;

namespace WebRequestorApp
{ 
  class Program {
    static void Main(string[] args) { 
      WebRequest req = WebRequest.Create ("http://www.google.com"); 
      WebResponse resp = req.GetResponse(); 
      StreamReader reader = new StreamReader(resp.GetResponseStream(), Encoding.ASCII); Console.WriteLine(reader.ReadToEnd()); 
    }
  }
}

Avviamo l’applicazione cliccando dal menù Debug su Start Without Debugging e dopo qualche istante vedremo codice HTML sul nostro schermo. Chiaramente l’HTML visto in questo modo non è facilmente comprensibile e la sua interpretazione è riservata ai browser che hanno il compito di inviare richieste ai server web e ricevere la relativa risposta, rendendola comprensibile agli utenti. Questo esempio serve solo a mostrare le caratteristiche di base di una richiesta web.

Il fondamentalmente il lavoro di un browser consiste nel creare una richiesta e inviarla ad un server web (tramite il corrispondente URL) e nel ricevere la risposta, presentando la stessa in una forma comprensibile agli utenti. La risposta solitamente consiste in un flusso (stream) di testo contenente tag HTML.

Sviluppando applicazioni in ASP.NET ci capiterà di avere a che fare spessissimo con il codice HTML. La maggior parte di questo codice viene generata automaticamente dai controlli lato server (server-side controls) ma in alcuni casi saremo noi stessi a dover scrivere codice HTML per personalizzare le nostre pagine o per creare un controllo personalizzato secondo le nostre esigenze.

Per esempio il seguente codice HTML genera una pagina contenente un pulsante e un menù a tendina:

<html> 
<body> 
<h2>Hello there. What's your favorite .NET feature?</h2> 
<select name='Feature'>
<option>Type-Safety</option> 
<option>Garbage collection</option> 
<option>Multiple syntaxes</option> 
<option>Code Access Security</option> 
<option>Simpler threading</option> 
<option>Versioning purgatory</option> 
</select><br/> 
<input type=submit name='Lookup' value='Lookup'></input> 
<br/> 
</body>
</html>

Si tratta di una pagina statica che consente di selezionare un valore e lavora soltanto localmente.

Internet Information Services (IIS)

Le prime applicazioni web residenti sui server avviavano un nuovo processo per ogni richiesta remota. Microsoft ha rivoluzionato questa concezione introducendo un singolo processo (chiamato servizio) che monitora la porta 80 in attesa di pacchetti di rete e carica le opportune librerie dinamiche (dynamik-link libraries, DLL) per la gestione di richieste separate. La piattaforma web standard di Microsoft è basata su Internet Information Services (IIS).

Fondamentalmente ogni applicazione web funziona allo stesso modo. Non importa quale piattaforma hardware o software si stia utilizzando ma deve essere sempre presente sul server un qualche tipo di software che monitori la porta 80 (quella tipicamente utilizzata) in attesa di richieste HTTP. Quando arriva una richiesta è compito del server rispondere alla stessa in qualche modo e sui sistemi operativi Microsoft è IIS il componente demandato a fare questo. Quando un browser effettua una chiamata ad un server con sistema Microsoft, IIS intercetta tale richiesta e ricerca la risorsa identificata tramite l’URL ricevuto.

IIS Suddivide la sua directory in diverse parti denominate directory virtuali. Per esempio supponiamo che qualcuno cerchi di accedere ad una risorsa web identificata dal seguente indirizzo:

http://www.miosito.com/prodotti/caratteristiche.htm

Chiaramente il dominio miosito è del tutto fittizio ma supponiamo che non lo sia. La parte http://www.miosito.com identifica il server di tale URL e invia la richiesta ad un labirinto di router. Quando la richiesta arriva al server esso verifica se la risorsa caratteristiche.htm è presente in una delle sue directory denominata prodotti. Se sul server gira IIS prodotti sarà una directory virtuale. Ogni directory virtuale tipicamente è correlata ad una singola applicazione e in pratica viene utilizzata per mappare una directory fisica (residente sul disco fisso del server) con un indirizzo internet. In questo modo IIS può gestire diverse applicazioni. Ogni directory virtuale include varie proprietà di configurazione tra cui anche opzioni di sicurezza, opzioni per la gestione degli errori e tante altre.

Sebbene per lo sviluppo di applicazioni ASP.NET non sia fondamentale conoscere le caratteristiche di IIS tale conoscenza diventa molto utile nel momento in cui ci si trovi ad effettuare il debug, il testing e la distribuzione di un’applicazione web e pertanto adesso vedremo a grandi linee il suo funzionamento.

Per aprire l’interfaccia utente di IIS basta andare nel Pannello di controllo , cliccare su Strumenti di amministrazione e poi su Internet Information Services. Si aprirà la seguente finestra (o molto simile, dipende dal vostro sistema operativo e dalla versione di IIS installata sul vostro computer)

Sulla sinistra è presente una struttura ad albero espandendo la quale è possibile visualizzare i siti web e le directory virtuali presenti sulla vostra macchina

Cliccando su un sito o una directory nella parte centrale della finestra viene visualizzato il relativo contenuto.

Cliccando con il tasto destro del mouse su un sito o una directory e selezionando la voce Proprietà si apre la finestra di configurazione in cui è possibile impostare diversi aspetti del sito e trarre anche molte utili indicazioni, come la versione di ASP.NET in uso sulla macchina

Chiaramente non è scopo di questa guida analizzare tutte le possibili opzioni di configurazione, tuttavia per i motivi suddetti vi consiglio di approfondire la conoscenza di IIS poichè successivamente vi potrà tornare molto utile.

I primi passi con ASP.NET

Il modo migliore per cominciare ad utilizzare ASP.NET è quello di creare una semplice applicazione. Per prima cosa creiamo una directory in cui inseriremo i file della nostra applicazione (nel mio caso C:esempioaspnet). Poi creiamo una directory virtuale in IIS, cliccando con il tasto destro su Sito web predefinito -> Nuovo -> Directory virtuale

Si apre la seguente finestra in cui dobbiamo inserire un nome per la nostra applicazione/sito web (nel mio caso SitoTest)

proseguendo si deve impostare il percorso fisico della cartella creata in precedenza (esempioaspnet)

infine impostiamo le autorizzazioni di accesso alla directory

In pratica l’alias SitoTest sarà il nome con cui l’applicazione verrà conosciuta dal mondo esterno.

A questo punto dobbiamo creare la nostra prima pagina HTML. Possiamo utilizzare tranquillamente un editor come il Notepad, oppure utilizzare Visual Studio. Siccome si tratta di un esempio molto semplice basta il Notepad, dunque apriamo un nuovo documento e scriviamo il seguente codice:

<html xmlns="http://www.w3.org/1999/xhtml"> 
<head> 
  <title>Pagina SitoTest</title> </head> 
<body>
  <h1> Hello World </h1> 
  Ciao questa è una prova 
</body>
</html>

salviamo il file con l’estensione htm (hello.htm) e inseriamolo nella directory C:esempioaspnet. A questo punto avviando un browser e digitando l’indirizzo http://localhost/SitoTest/hello.htm il risultato sarà il seguente.

In pratica il browser invia una richiesta HTTP al server per il file hello.htm e IIS restituisce il contenuto del file al browser. Poichè il testo contiene tag HTML il browser ne comprende il contenuto e visualizza correttamente quello che ci aspettiamo. Fino a questo momento però non siamo di fronte ad una pagine ASP.NET, ma ad una semplice pagina HTML.

Per effettuare la conversione da HTML a ASP.NET occorrono due passaggi: aggiungere in cima al file hello.htm una riga di codice (la direttiva Page) e rinominare il file stesso da hello.htm ad hello.aspx. In questo modo avremo una versione del nostro programma che opera utilizzando il framework ASP.NET

<%@ Page Language="C#" %>
<html xmlns="http://www.w3.org/1999/xhtml"> 
<head> 
  <title>Pagina SitoTest</title> </head> 
<body>
  <h1> Hello World </h1> 
  Ciao questa è una prova
</body>
</html>

Il risultato rimane visivamente invariato ma la direttiva Page viene utilizzata dall’ambiente di esecuzione ASP.NET nella compilazione del file e suggerisce di compilare questo codice interpretando eventuali istruzioni poste al suo interno sottoforma di codice C#.

E’ possibile inserire codice eseguibile nella nostra pagina semplicemente nel modo seguente:

<body>
 <h1> Hello World </h1> 
<%
.......
this.Metodo1();
this.Metodo2();
.......
%>
</body>

E ' anche possibile inserire blocchi di codice che deve essere eseguito sul server. Per fare ciò si utilizza l’attributo runat:

<%@ Page Language="C#" Debug="true" %>

<script runat="server"> 
void MetodoTest() {
  //Metodo che fa qualcosa 
}
</script>

<html> 
<body> 
  <h1>Hello World</h1> 
<% 
MetodoTest(); 
%>
</body>
</html>

Iniziamo a lavorare con Visual Studio

Visual Studio 2010 mette a disposizione diverse opzioni per il dislocamento dei nostri siti web durante lo sviluppo. La procedura di creazione guidata di un sito mette a disposizione le seguenti locazioni: IIS locale, file system, sito FTP e sito remoto. Ovviamente le diverse scelte dipendono degli scenari di utilizzo e adesso vedremo le differenze tra di esse.

IIS locale

Creare un sito web che gira su IIS locale è molto simile a ciò che si faceva con le vecchie versioni di Visual Studio, specificando una directory locale virtuale. Questa opzione consente dunque di creare siti che vengono gestiti dall’IIS presente sul computer locale. Le pagine dei siti vengono memorizzate nella tipica directory Inetpubwwwroot.

File System

Questa opzione consente di sviluppare siti web ponendoli in qualsiasi cartella sul proprio computer o su una cartella condivisa di un altro computer. Questa opzione non richiede che sul computer sia installato IIS e l’esecuzione delle pagine avviene tramite il server web di Visual Studio. Questo è l’approccio più comune nella creazione, sviluppo e test di siti web. Quando poi il sito è terminato basta creare una directory virtuale IIS sul server sul quale deve essere posizionato il sito e trasferire tutto il contenuto della cartella locale in tale directory.

FTP

E’ possibile utilizzare Visual Studio per gestire siti web disponibili attraverso un server FTP. Se per esempio si lavora con una compagnia che offre servizi di hosting di siti web, un server FTP offre un modo comodo di trasferire i relativi file tra la nostra postazione di sviluppo e il server su cui risiede il sito. Visual Studio è in grado di connettersi con qualsiasi server FTP sul quale si dispone di privilegi di lettura e scrittura.

Siti web remoti

Quest’ultima opzione prevede l’utilizzo di un IIS su un computer accessibile attraverso la rete. Oltre ad IIS tale computer deve avere installato FrontPage 2002 Server Extensions. Questa opzione è utile quando un sito web viene sviluppato contemporaneamente da diverse persone che si trovano in luoghi diversi. Operando da remoto l’intero gruppo di sviluppo può lavorare simultaneamente. La controindicazione è che le operazioni di debugging e configurazione sono molto più lente che in locale.

I primi passi con Visual Studio

Per cominciare ad utilizzare Visual Studio 2010 creiamo un’applicazione simile a HelloWorld vista nella lezione precedente. Per fare questo avviamo l’ambiente di sviluppo e clicchiamo dal menù File su New -> Web Site. Si apre la seguente finestra di dialogo in cui dobbiamo selezionare il tipo di progetto Empty Web Site

scegliamo inoltre come opzione Web location HTTP.

In base alle scelte fatte Visual Studio genera come impostazione predefinita un file di soluzione ASP.NET in una directory denominata VisualStudio2010Projects, posta nella cartella Documenti del computer in uso. Inoltre viene generata una directory virtuale in inetpubwwwroot che rappresenta la cartella fisica posta in Projects.

Se avessimo scelto come modello di progetto ASP.NET Web Site sarebbe stata creata una struttura simile con la differenza che sarebbero stati già inclusi nel progetto un web form e il relativo file di codice (default.aspx e default.aspx.cs). Sarebbe inoltre stata creata automaticamente una cartella denominata App_Data da utilizzare per dati pertinenti al nostro sito.

A questo punto nella finestra Solution Explorer clicchiamo con il tasto destro del mouse sul nostro sito web e scegliamo l’opzione Add New Item

Nella finestra di dialogo che compare scegliamo l’elemento Web Form e diamogli il nome che vogliamo (nel mio caso Test.aspx)

Lasciamo le altre opzioni come sono anche se voglio soffermarmi un attimo sull’opzione Place code in separate file presente in basso a destra nella finestra di dialogo. Tale opzione in pratica indica a Visual Studio di creare un file .cs separato in cui porre il codice C# del web form.

Non mi soffermo più di tanto sul layout di Visual Studio perchè non è scopo di questa guida analizzarne i diversi componenti ma vi faccio notare in basso le tre tab Design, Split e Source. Cliccando sul tab Design è possibile visualizzare l’aspetto del web form in modo del tutto simile a quello che verrebbe visualizzato in un browser (in questo momento se clicchiamo sul tab Design del nostro web form chiaramente vedremo una pagina bianca). Cliccando su Source visualizziamo il codice HTML, mentre Split permette di visualizzare contemporaneamente la parte grafica e il codice HTML (la finestra viene suddivisa in due parti).

Se espandiamo il nodo relativo al nostro web form vedremo il file Test.aspx.cs in cui scrivere il nostro codice C#

Facendo doppio click su questo file si aprirà una pagina simile alla seguente

Nello stesso modo in cui abbiamo operato per il programma di esempio fatto con il Notepad possiamo creare nel file .cs un metodo:

public partial class Test : System.Web.UI.Page
{
  protected void Page_Load(object sender, EventArgs e)
  {
    // ...
  }

  public void Metodo1()
  {
    // Fa qualcosa
  }
}

e chiamarlo dal file .aspx:

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Test.aspx.cs" 
Inherits="Test" %>

<!DOCTYPE html PUBLIC "
-//W3C//DTD XHTML 1.0 Transitional//EN" 
"http://www.w3.org/TR/
xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
  <title></title>
</head>
<body>
  <form id="form1" runat="server">
  <div>
  <% 
  Metodo1(); 
  %>
  </div>
  </form>
</body>
</html>

Quando compiliamo l’applicazione Visual Studio compila il file .aspx e il file .cs e li pone nella directory temporanea ASP.NET. Successivamente IIS carica i file compilati (DLL) e mostra la pagina che abbiamo appena creato.

Utilizzo e gestione di controlli generici

Lo sviluppo di un’applicazione web in Visual Studio è molto simile a quello di un’applicazione desktop poichè con questo strumento di sviluppo non dobbiamo spendere molto tempo nella scrittura di codice complesso, che viene invece generato automaticamente tramite strumenti visuali. Per imparare ad utilizzare Visual Studio la cosa migliore è quella di sviluppare una semplice pagina web che utilizzi controlli lato server.

Avviamo dunque Visual Studio e creiamo un nuovo progetto di tipo Web Site. Clicchiamo nella finestra Solution Explorer con il tasto destro del mouse sul progetto appena creato e selezioniamo Add -> New Item. Nella finestra di dialogo che si apre selezioniamo Web Form e denominiamolo Default.aspx. A questo punto clicchiamo sul tab Design e siamo pronti a lavorare sulla nostra pagina

Visual Studio genera automaticamente il codice ASP.NET relativo alla pagina. Se clicchiamo sul tab Split il designer viene suddiviso in due parti, quella inferiore è la rappresentazione grafica della pagina mentre quella superiore è il corrispondente codice ASP.NET. Se inseriamo una frase nella parte grafica vedremo che simultaneamente Visual Studio lo inserirà nel codice ASP.NET

Per modificare il formato del testo è necessario agire sulle proprietà della pagina. Selezioniamo il testo, clicchiamo con il tasto destro sopra e selezioniamo la voce Properties. Nella finestra laterale Properties selezioniamo la voce Style e clicchiamo sul pulsante con i tre puntini (ellipsis). Si apre la finestra di dialogo Modify Style, tramite la quale possiamo impostare diverse proprietà

Scegliamo un tipo di carattere che ci piace e le relative dimensione e altezza e clicchiamo su OK

Notiamo ancora una volta come Visual Studio traduce in codice le impostazioni che abbiamo fatto

A questo punto trasciniamo sulla nostra pagina una label dalla finestra Toolbox

Nella finestra Properties relativa alla label appena inserita scriviamo nella proprietà Text la frase 'Scrivere qualcosa’. Vedremo immediatamente che sia la pagina visuale sia il file aspx vengono aggiornati

E’ chiaramente possibile personalizzare l’apparenza della label attraverso la finestra di dialogo Properties in modo del tutto analogo a quanto fatto per il web form.

Aggiungiamo ora una textbox accanto alla label e un dropdownlist sotto

Clicchiamo sull’opzione Edit Items nel menù DropDownListTasks e si aprirà una finestra in cui inserire i valori che tale controllo dovrà presentare agli utenti

ad ogni elemento è possibile associare un testo (che sarà quello visualizzato in fase di esecuzione dell’applicazione) e un corrispondente valore.

Aggiungiamo infine un button alla nostra pagina

Facciamo doppio click sul button e vedremo che nel file Default.aspx.cs verrà generato il corrispondente evento Click

Se guardiamo invece il codice ASP.NET generato da Visual Studio in seguito alle nostre operazioni di posizionamento dei controlli dovremmo vedere qualcosa del genere

cioè tutte le nostre operazioni fatte graficamente sono state tradotte in codice.

Se come ultimo passaggio vogliamo verificare il funzionamento dell’evento Click del button inseriamo in esso il seguente codice

Se avviamo ora l’applicazione, inseriamo il testo 'ABCDEF’ nella textbox, selezioniamo l’elemento 'Tre’ nella dropdownlist e clicchiamo sul button il risultato sarà il seguente

Chiaramente lo scopo della guida non è analizzare tutte le caratteristiche dei controlli a disposizione, poichè servirebbe una guida solo per questo, ma quello di farvi intuire la semplicità con cui Visual Studio consente la gestione e l’utilizzo degli stessi. Per approfondire il funzionamento dei controlli utilizzati nella presente lezione e di tutti gli altri controlli generici vi invito a consultare la documentazione ufficiale Microsoft.

Utilizzo e gestione di controlli di validazione

L’obiettivo fondamentale di ASP.NET e del .NET Framework è quello di rendere più semplice e veloce il lavoro dei programmatori. Per tale motivo nel framework sono state incluse diverse funzionalità che in precedenza i programmatori dovevano gestire autonomamente, esponendosi a perdite di tempo e potenziali errori.

Uno scenario molto comune quando si naviga è quello di imbattersi in siti che includono pagine nelle quali gli utenti si trovino a dover inserire diversi tipi di informazioni. Per esempio per accedere ad una determinata sezione di un sito web gli utenti potrebbero dover inserire username o password o per ricevere determinate informazioni devono fornire un indirizzo email valido (contenete @, dominio, ecc).

Colui che gestisce un sito del genere deve dunque poter contare su una logica che assicuri che le informazioni inserite siano valide. Siccome non è possibile che nel 100% dei casi gli utenti inseriscano dati assolutamente validi è necessario validare le informazioni inserite. Per esempio certi campi possono essere obbligatori, altri possono richiedere che i dati inseriti rispettino un certo formato (come il suddetto indirizzo email), altri ancora che il dato inserito sia compreso in un certo intervallo e così via.

Chiaramente questi controlli potrebbero essere effettuati dai programmatori scrivendo codice ad hoc ma ASP.NET fornisce un metodo più semplice e veloce: i controlli di validazione. Questi operano in stretta relazione con i controlli standard (come le textbox) presenti nei web form e permettono di ottenere messaggi di errore o avvertimento se gli utenti inseriscono infermazioni che potrebbero essere non corrette.

ASP.NET include sei controlli di validazione:

  • RequiredFieldValidator: assicura che un campo non sia vuoto
  • RangeValidator: assicura che il valore contenuto in un campo sia compreso in un certo intervallo
  • RegularExpressionValidator: valida i dati presenti in un campo confrontando la loro struttura con un modello predefinito (es. l’indirizzo email)
  • CompareValidator: assicura che il valore contenuto in un campo corrisponda ad uno specifico valore
  • CustomValidator: permette di impostare delle funzioni di validazione personalizzate
  • ValidationSummary: permette di visualizzare un elenco di tutti gli errori di validazione presenti in una pagina

Tutti i controlli di validazione operano allo stesso modo. Prima si pone un controllo standard sulla pagina web e poi si pone il controllo di validazione che si preferisce nel punto in cui dovrà coparire l’eventuale messaggio d’errore. I controlli di validazione presentano una proprietà denominata ControlToValidate, nella quale bisogna impostare il nome del controllo che deve essere validato. Impostata questa proprietà tutto funziona automaticamente, anche se ovviamente occorre configurare il messaggio che deve essere restituito ed è possibile anche configurare diverse altre proprietà.

I controlli di validazione operano sui seguenti controlli server: TextBox, ListBox, DropDownList, RadioButtonList, HtmlInputText, HtmlInputFile, HtmlSelect, HtmlTextArea, FileUpload. Per comprendere meglio che funzionano come al solito facciamo un esempio.

Apriamo il sito di prova creato nella lezione precedente o creiamone uno nuovo. Aggiungiamo un web form denominato Validazione.aspx che ospiterà i controlli standard e i relativi controlli di validazione. Supponiamo che sia una pagina in cui un ipotetico utente deve inserire nome, cognome, età, numero di telefono e password (in due diversi campi per confermare che sia corretta). Inseriamo pertanto tante textbox quanti sono i campi, le relative label e un pulsante per l’invio delle informazioni inserite

Adesso inseriamo i controlli di validazione. Poniamo i RequiredFieldValidator ognuno accanto ai campi Nome, Cognome, Età, Telefono, Password e Conferma Password impostando la proprietà ControlToValidate sulle rispettive textbox ed impostando i messaggi d’errore

Infine inseriamo nella pagina un ValidationSummary che ci permetterà di visualizzare contemporaneamente tutti i messaggi d’errore. E’ inoltre possibile impostare la proprietà ShowMessageBox di tale controllo al valore true per ricevere anche una segnalazione visuale degli errori. A questo punto avviamo l’applicazione e se clicchiamo sul pulsante di invio dei dati senza inserire alcuna informazione vedremo qualcosa del genere

Se proviamo ad inserire delle informazioni in alcuni campi vedremo che alcuni messaggi (quelli relativi ai campi compilati) non appariranno più

In questo esempio abbiamo utilizzato solo i RequiredFieldValidator ma chiaramente l’utilizzo degli altri tipi di controlli di validazione è simile. Come al solito vi invito a consultare la documentazione ufficiale Microsoft per approfondire l’argomento.

Utilizzo e gestione di controlli grafici

Le pagine web contengono spesso diverse immagini e il linguaggio HTML utilizza un opportuno tag (img) per indicare al browser di caricare un’immagine e visualizzarla. ASP.NET rende trasparente ai programmatori l’uso del tag img tramite l’utilizzo del controllo server Image che permette di gestire file di questo tipo traducendo in codice le sue impostazioni.

Utilizzare il controllo Image è molto semplice, basta trascinarlo dal Toolbox su un web form come tutti gli altri controlli HTML. Effettuata questa operazione viene generato un tag <img/>

In aggiunta a tale controllo ASP.NET mette a disposizione altri due controlli molto utili: ImageButton, è un pulsante in cui si può impostare come sfondo un’immagine; ImageMap, che consente di mappare un’immagine e dividerla in zone che reagiscono diversamente in base al click dell’utente (si pensi ad esempio ad una cartina geografica in cui cliccando sulle diverse regioni si apre una pagina con le relative caratteristiche).

Creiamo un nuovo web form e trasciniamo dal Toolbox un controllo Image in esso. Nella finestra Properties del controllo inseriamo un percorso ad un’immagine presente sul nostro computer nella proprietà ImageUrl. In pratica se clicchiamo sul pulsante a destra di tale proprietà comparirà una finestra di dialogo con gli elementi presenti nel nostro progetto (quindi prima inseriamo l’immagine nel progetto). Ad esempio io ho aggiunto l’immagine Collineazzurre.jpg al mio progetto e la posso selezionare in tale finestra

dopo aver cliccato su OK ecco come apparirà la pagina

Avviando l’applicazione vedremo nel nostro browser una pagina contenente solo l’immagine.

Adesso aggiungiamo un controllo ImageButton alla nostra pagina. Come accennato in precedenza si tratta di un pulsante che è possibile decorare con una certa grafica. Tramite questo controllo è possibile gestire tre possibili scenari: nel primo l’ImageButton funziona come un semplice Button al quale è possibile collegare l’evento Click sul server; nel secondo è possibile definire uno script lato client e collegare la proprietà OnClientClick del controllo a tale script; nel terzo è possibile indicare al controllo di inviare la prossima richiesta ad una pagina specifica attraverso la proprietà PostBackUrl. Anche in questo controllo è necessari valorizzare la proprietà ImageUrl per indicare l’immagine da visualizzare

Se nella proprietà OnClientClick scriviamo Test il codice ASP.NET verrà modificato nel modo seguente

e quando si cliccherà sul pulsante verrà cercato lo script Test (otterrete un errore se lo script non esiste)

Se invece nella proprietà PostBackUrl scriviamo ~/Validazione.aspx (la pagina creata qualche lezione fa) al click del pulsante verremo reindirizzati a tale pagina.

Adesso aggiungiamo un controllo ImageMap e impostiamo come proprietà ImageUrl un’immagine qualunque (io utilizzo di nuovo "Colline azzurre.jpg"). Tra le proprietà del controllo vi è anche Hotspots. Clicchiamo su tale proprietà e vedremo una finestra in cui è possibile definire i cosiddetti hotspot (aree interattive) dell’immagine. Il pulsante Add permette di scegliere che tipo di hotspot inserire (circolare, rettangolare o poligonale). Inseriamo un hospot rettangolare

Impostiamo dei valori per il posizionamento e una stringa (Prova) nella proprietà AlternateTex

Avviando l’applicazione; posizionando il mouse nella zona definita comparrirà il testo Prova e cliccando verremo indirizzati alla pagina Validazione.aspx (impostata nella proprietà NavigateUrl)

Interfaccia utente e master pages

Un segno distintivo dei moderni siti web è sicuramente la cura nei dettagli e la semplicità di uso delle varie pagine che li compongono. Per esempio i siti più apprezzati si basano su schemi di colore e insiemi di caratteri uguali in ogni pagina ed inoltre forniscono semplici e intuitivi strumenti di navigazione tra le pagine stesse. Del resto sarà capitato un pò a tutti di accedere a siti aventi pagine tutte diverse tra loro e di difficile consultazione, ecco questo è quello che dobbiamo evitare per i nostri siti.

La soluzione per dare alle pagine di un sito un aspetto comune è quella di creare una classe primaria dalla quale tutte le pagine del sito derivino. Siccome ASP.NET si basa su un modello incentrato sulla classe Page basta implementare una pagina primaria (Primary Page) le cui proprietà saranno ereditate dalle pagine del nostro sito

Tutte le pagine .aspx derivano dalla pagina primaria che a sua volta deriva da System.Web.UI.Page. La pagina primaria si occupa del caricamento degli elementi comuni tra le varie pagine e successivamente ogni singola pagina si occupa del resto.

Lo strumento messo a disposizione da ASP.NET per realizzare questo tipo di struttura è la cosiddetta Master Page. Queste pagine sono del tutto simili ad una tipica pagina di un sito e vengono definite in file con estensione .master.

Una master page serve dunque come un modello e quando un utente naviga su una pagina che dipende da una master page le richieste e le risposte sono filtrate da quest’ultima. ASP.NET unisce poi la master page e la pagina di contenuti (.aspx) in un’unica classe. Quando la pagina di contenuti viene richiesta la master page inserisce il proprio contenuto nel file .aspx sottoforma di un controllo che viene aggiunto alla collection di controlli della pagina.

Vediamo adesso come fare a definire e utilizzare una master page. Avviamo Visual Studio e creiamo un nuovo progetto di tipo Empty Web Site. Aggiungiamo un nuovo elemento di tipo Master Page al nostro progetto

La pagina a livello visuale è simile ai normali web form visti nelle lezioni precedenti e il codice generato da Visual Studio è il seguente

Vi faccio notare che è stato inserito il controllo ContentPlaceholder di cui parleremo in seguito. Per il resto la master page può essere personalizzata a nostro piacimento come una normale pagina del nostro sito.

Per esempio andiamo a modificare il tag body impostando un colore di sfondo (background) diverso

la master page adesso ha uno sfondo grigio (#bbbbbb).

Aggiungiamo adesso al nostro progetto un nuovo elemento di tipo web form (lo chiamo Default.aspx), spuntando in basso nella finetra di dialogo Add New Item l’opzione Select master page

Cliccando su OK ci veine presentata un’altra finestra di dialogo nella quale possiamo selezionare la master page per la pagina che stiamo aggiungendo al progetto (nel nostro caso ce ne sarà soltanto una)

Se andiamo a guardare nel tab Design la pagina Default.aspx vedremo che essa ha lo stesso colore di sfondo della master page e questo dimostra che la pagina ha ereditato le impostazioni del modello.

Questo è il codice generato da Visual Studio per la pagina Default.aspx

in esso si vede il riferimento alla pagina MasterPage.master.

A questo punto noi possiamo creare tutte le pagine che vogliamo (ognuna con contenuti personalizzati) e le dobbiamo legare alla nostra master page. Se successivamente andremo a modificare il contenuto della master page in un’unica operazione saranno aggiornate tutte le pagine che dipendono da essa.

Chiaramente quello presentato è un semplice esempio ma che lascia intuire la potenzialità di questi strumenti, soprattutto all’interno di siti con una grafica complessa.

Temi e skin

Come abbiamo visto le master page influiscono sulla struttura generale di una serie di pagine all’interno di un’applicazione (o sito) web. Tuttavia quasi sempre nell’implementazione di un sito si ha la necessità di gestire altri elementi che possono cambiare da pagina a pagina ma devono mantenersi costanti all’interno di una stessa pagina (come il tipo di carattere dei testi). In tali scenari uno strumento molto utile sono i cosiddetti Temi.

Se avete una certa familiarità con i Cascading Style Sheets (CSS) non vi verrà difficile comprendere il funzionamento dei temi. Le due tecniche infatti sono similari poichè con entrambe è possibile definire lo stile visuale delle nostre pagine web. E’ possibile utilizzare i temi per specificare stili, elementi grafici ed altri elementi nelle pagine dei nostri siti.

I temi sono fondamentalmente dei file testuali che specificano le caratteristiche che gli elementi di una pagina devono assumere e ASP.NET ne include diversi predefiniti, anche se è possibile ovviamente definirne di personalizzati.

Procediamo con un esempio. Creiamo un nuovo web form (io lo chiamo EsempioTemi.aspx) e successivamente clicchiamo con il tasto destro del mouse sul nostro progetto e scegliamo l’opzione Add ASP.NET Folder e scegliamo come tipo di cartella Theme

Questa operazione porta alla creazione della cartella App_Themes con all’interno una cartella predefinita (denominata Theme1)

Rinominiamo la cartella Theme1 in Default e clicchiamo su di essa con il tasto destro del mouse, aggiungendo un nuovo elemento di tipo StyleSheet (foglio di stile). Denominiamo lo stesso Default.css

A questo punto dobbiamo impostare le caratteristiche del nostro foglio di stile. Se facciamo doppio click su di esso vedremo che contiene soltanto un tag body

Per aggiungere nuovi elementi clicchiamo sull’opzione Add Style Rule del menù Styles

Si apre la seguente finestra

Supponiamo di voler inserire un elemento H1 al nostro foglio di stile. Selezioniamo nel menù a tendina Element l’elemento h1 e clicchiamo sul pulsante > per inserirlo nella lista Style rule hierarchy

Cliccando su OK vediamo immediatamente che il foglio di stile viene modificato nel seguente modo

Per modificare l’elemento appena inserito clicchiamo con il tasto destro del mouse sul relativo tag e scegliamo l’opzione Build Style. In questo modo si apre la finestra Modify Style, nella quale andiamo ad impostare alcune proprietà a nostro piacimento

Dopo aver cliccato su OK vediamo le nostre scelte inserite nel foglio di stile

Testiamo adesso il nostro tema aggiungendo al web form creato all’inizio della lezione la direttiva Theme e scrivendo qualcosa all’interno di tag h1

Il testo che ho inserito io è Test applicazione stile ed esso verrà visualizzato nel browser in base alle ipostazioni del nostro foglio di stile

La stessa cosa avverrà per tutti gli elementi della nostra pagina racchiusi tra tag h1. Chiaramente abbiamo utilizzato questo tag come esempio ma in linea di principio in modo del tutto simile è possibile personalizzare tutti gli elementi di un web form.

Infine vorrei soffermarmi brevemente anche sulle cosiddette skin. Questi elementi rappresentano un modo di configurare alcune proprietà di un gruppo di controlli. Per esempio si potrebbero voler definire diversi schemi di colori per un particolare tipo di controllo (come TextBox) caratterizzato da diverse proprietà personalizzabili.

Definendo le opportune skin è possibile rendere disponibili un certo numero di opzioni di visualizzazione per un gruppo di controlli senza la necessità di impostare le proprietà di ogni istanza di ciascuno di essi. Se ad esempio un web form contiene dieci TextBox e si vuole dare ad esse una certa formattazione basta definire l’opportuna skin e assegnarla ad ognuna delle caselle di testo. Quindi il file di una skin definisce uno specifico tipo di controllo e gli attributi da applicare a tutte le istanze dello stesso.

Vediamo un esempio. Creiamo una nuova cartella denominata Skins all’interno della cartella Default vista in precedenza e aggiungiamo al suo interno un nuovo elemento di tipo skin denominato TestSkinFile

Nel file generato inseriamo delle personalizzazioni per alcuni controlli come le seguenti

In questo modo quando aggiungeremo ad un web form gli elementi definiti nella skin essi assumeranno le caratteristiche impostate. Ovviamente affinchè avvenga questo è necessario dichiarare la skin all’interno della pagina, in modo analogo a quanto fatto in precedenza per il tema.

I file di configurazione: machine.config e web.config

Un aspetto importante delle applicazioni web è la gestione delle informazioni di configurazione, ambito che include diversi elementi tra cui:

  • Session state
  • Caching
  • Tracing
  • Autenticazione

Questi elementi sono controllabili attraverso un certo numero di parametri configurabili. Per esempio quando in un’applicazione si abilita il session state (stato della sessione) è possibile stabilire dove collocare tale gestione, potendo scegliere ad esempio tra un processo o un computer separato (utilizzando Windows Service o SQL Server). E’ inoltre possibile configurare la durata dello stato della sessione e le modalità in cui l’applicazione deve tenere traccia di tali informazioni (ad esempio tramite cookie).

Anche il caching è un elemento molto importante poichè quando si decide di mettere in cache i contenuti del proprio sito web questa caratteristica permette di configurare la durata della permanenza dei contenuti nella cache e la posizione in cui devono essere memorizzati (sul server, sul client, sul proxy).

Le opzioni di configurazione di queste due funzionalità vengono gestite tramite opportuni file di configurazione. Nelle prime versioni di ASP.NET modificare la configurazione di un’applicazione web significava operare direttamente sul file di configurazione in formato XML. Fortunatamente invece le più recenti versioni di ASP.NET (dalla 2.0 in poi) mettono a disposizione due strumenti che rendono la configurazione di un’applicazione web molto più semplice. Il primo strumento è la sezione ASP.NET Configuration disponibile in IIS (versione 7), il secondo è il Web Site Administration Tool disponibile in Visual Studio (che vedremo più avanti).

I file di configurazione .NET sono file XML con un contenuto che viene compreso dall’ambiente di esecuzione del .NET Framework. In fase di esecuzione questi file vengono letti per impostare i vari parametri necessari e tali parametri sono cumulativi. Per esempio il file di configurazione web.config viene caricato quando viene avviata l’applicazione ma il primo file di configurazione che viene esaminato è il machine.config e le impostazioni dei due file vengono seguite entrambe.

Il file machine.config solitamente è posto nel percorso C:WindowsMicrosoft.NETFrameworkvxxxxxConfig (dove xxxxx è la versione del .NET Framework). Questo file imposta il comportamento predefinito di tutte le applicazioni .NET eseguite sul computer locale. Di seguito un esempio di tale file

Si nota la presenza di diverse sezioni di configurazione. Tra le varie è possibile ad esempio trovare la seguente

che indica all’ambiente di esecuzione ASP.NET di utilizzare la Forms Authentication (una delle opzioni di autenticazione disponibili) per autenticare gli utenti del sito. Viene inoltre specificato di utilizzare SQL Server per la gestione del session state, con un timeout di 25 minuti, e di tracciare tale stato direttamente nell’URI.

Il machine.config dunque permette di gestire le impostazioni predefinite del nostro computer e questo ha determinati effetti su tutte le applicazioni .NET. Per tale motivo non è generalmente una buona idea apportare modifiche dirette al file. In alternativa le applicazioni windows form .NET dipendono anche da un file di configurazione separato e denominato solitamente come l’eseguibile delle stesse (se ad esempio l’eseguibile dell’applicazione si chiama miaapplicazione.exe il file di configurazione associato sarà miaapplicazione.exe.config). Le applicazioni web .NET invece dipendono da un file denominato web.config. Tali file devono essere inclusi nella cartella in cui risiede l’applicazione.

Un esempio di file web.config è il seguente

Nelle versioni di ASP.NET precedenti alla 2.0 i file web.config dovevano essere modificati manualmente senza alcuno strumento di supporto che assicurasse che quello che si scriveva al loro interno fosse corretto.A partire da ASP.NET 2.0 invece è disponibile in Visual Studio un nuovo strumento denominato Web Site Administration Tool (WSAT).

Vediamo brevemente come funziona. Creiamo un nuovo progetto web in Visual Studio o apriamone uno già esistente (vanno bene quelli creati in precedenza) e dal menù Website clicchiamo su ASP.NET Configuration

Si apre la seguente pagina di configurazione

attraverso cui è possibile modificare il file web.config senza dover scrivere il codice manualmente. Clicchiamo per esempio sul tab Applicazione e al suo interno clicchiamo sul link Crea Impostazioni Applicazioni

Inseriamo un’impostazione denominata Proprietario il cui valore sia Pippo e salviamo

Se andiamo a guardare il web.config vedremo che la nuova impostazione è stata inserita automaticamente

In modo del tutto simile è possibile configurare le impostazioni di sicurezza e le impostazioni del provider tramite le altre tab presenti nella pagina.

Gestire la sicurezza delle applicazioni ASP.Net

Spesso un sito web contiene delle pagine che non devono essere disponibili ad essere consultate da chiunque, ma soltanto da determinati tipi di utenti. Si parla di autenticazione degli utenti in riferimento alla pratica utilizzata per verificare che gli utenti siano effettivamente quelli che dicono di essere e tale pratica si basa su un’informazione condivisa (come una password). Si parla invece di autorizzazione degli utenti in riferimento alla pratica di consentire o negare in base a permessi e/o ruoli loro assegnati il permesso di accedere a certe pagine a determinati utenti che si sono autenticati.

La sicurezza del software è un argomento di grande attualità in negli ultimi anni. Quando un’applicazione web viene eseguita in un ambiente Microsoft occorre considerare alcuni fondamentali aspetti: il contesto di sicurezza (security context) di IIS, la modalità di autenticazione degli utenti ed i relativi permessi.

Gestire la sicurezza sul web è un’attività molto simile alla tipica gestione della sicurezza di una rete in cui bisogna basarsi sull’autenticazione e sulle autorizzazioni degli utenti. Tuttavia la sicurezza sul web contempla la gestione di client che utilizzano diverse piattaforme, quindi si dispone di un controllo minore rispetto ad una rete chiusa (come la rete Windows di un ufficio). In una rete chiusa infatti un amministratore può più facilmente sorvegliare l’intero sistema, garantendo o negando l’accesso dei vari utenti alle risorse disponibili. Gli utenti di un’applicazione web invece sono molto più numerosi ed è quindi necessario un altro approccio (esterno all’infrastruttura Windows) per autenticare ed autorizzare gli stessi.

Il prima problema relativo alla sicurezza che si incontra sviluppando applicazioni web in ambiente Windows è quello di comprendere il contesto di sicurezza di IIS. Virtualmente tutti gli accessi ad un sito web passano attraverso IIS e, come tutte le applicazioni Windows, IIS viene eseguito in uno specifico contesto. Quando IIS viene installato su un computer il processo di installazione crea una identità di sicurezza (security identity) separata per esso.

E’ possibile individuare l’identità sotto la quale la nostra versione di IIS gira avviandolo, selezionando una directory virtuale, accedendo alla finestra delle proprietà e cliccando su Controllo autenticazione e accesso remoto. A questo punto si apre la seguente finestra

come potete vedere sul mio computer l’identità è IUSR.

Come impostazione predefinita IIS gestisce le directory virtuali utilizzando l’Anonymous Authentication. Quando è specificata tale modalità IIS utilizza l’utenza che abbiamo appena visto e rende disponibili le risorse da essa accessibili. IIS supporta anche altri tipi di autenticazione, tra cui l’autenticazione Windows. In quest’ultimo caso è necessario fornire a tutti i potenziali utenti nome utente e password di Windows. Tuttavia questo tipo di autenticazione funziona bene con utenti che utilizzano sistemi Windows ma per gli utenti che utilizzano altri sistemi operativi è necessario utilizzare un altro tipo di autenticazione, poichè il meccanismo di sicurezza disponibile agli utenti Windows non è disponibile per gli altri sistemi e dunque gli utenti non potrebbero autenticarsi.

Fortunatamente però ASP.NET include la cosiddetta Forms Authentication, un semplice ma efficace strumento introdotto nella verisone 1.0. Esso viene impostato dal file web.config di un’applicazione web che, oltre agli elementi già visti, contiene anche i nodi di autenticazione e di autorizzazione. In assenza di tali nodi ASP.NET consente un accesso senza limitazioni ad un sito web. Se invece questi elementi sono presenti gli utenti vengono reindirizzati ad una pagina dedicata all’autenticazione (tipicamente una pagina di login in cui gli utenti devono inserire username e password).

Ecco un esempio di web.config con i suddetti nodi

in esso si può vedere che è stato impostato come metodo di autenticazione Form e come pagina alla quale gli utenti vengono reindirizzati la pagina login.aspx.

ASP.NET include un grande supporto per l’autenticazione degli utenti. L’elemento fondamentale in tale contesto è la classe FormsAuthentication, la quale fornisce una serie di diverse funzionalità che vanno dalla crittografia delle password, alla creazione di cookie di autenticazione, passando per tutta una serie di altri aspetti

Per approfondire la tematica della sicurezza in ambiente ASP.NET vi invito a consultare un articolo scritto da me e presente a questa pagina.

Gestione degli utenti

ASP.NET e Visual Studio forniscono anche utili strumenti per la gestione dell’identità e dei ruoli degli utenti di un sito web. Per vedere come fare creiamo un nuovo sito web e quindi accediamo alla pagina ASP.NET Configuration che abbiamo visto qualche lezione fa. In essa selezioniamo la tab Provider e clicchiamo sul link Selezionare un unico provider per tutti i dati di gestione del sito

quindi clicchiamo sul link Prova per verificare che la connessione funzioni

e se tutto è a posto dovrebbe comparirvi la seguente pagina

Per assicurarsi che il database funzioni clicchiamo poi sulla tab Sicurezza e aggiungiamo un utente direttamente da qui, cliccando su Crea utente ed inserendo i relativi dati nella seguente finestra

E’ anche possibile cambiare il tipo di autenticazione sempre dalla tab Sicurezza cliccando sul link Seleziona tipo di autenticazione e scegliendo una delle due opzioni disponibili (scegliamo la prima opzione)

Sempre nella tab Sicurezza clicchiamo su Abilita ruoli

e poi su Crea o gestisci ruoli

Creiamo due ruoli: Admin e Utente

A questo punto andiamo a creare altri utenti nel modo visto in precedenza (io creo gli utenti Vincenzo e Paolo). Notiamo che a differenza di prima adesso accanto all’utente è possibile selezionare i ruoli cui esso deve appartenere e io assegno all’utente Vincenzo il ruolo Admin e all’utente Paolo il ruolo Utente

Se andiamo ad aprire il file web.config vedremo in esso i parametri di autenticazione che abbiamo impostato

Dobbiamo adesso andare ad impostare le autorizzazioni di accesso alle varie risorse del sito per i vari ruoli e/o utenti. Sempre attraverso la tab Sicurezza clicchiamo allora su Crea regole di accesso e tramite la seguente pagina

potremo impostare i privilegi nel modo desiderato. Per esempio possiamo negare l’accesso agli utenti anonimi spuntando l’opzione Utenti anonimi e l’opzione Nega. Cosa che determina l’inserimento nel web.config del seguente codice

Nella prossima lezione vedremo come gestire i controlli per il login.

Utilizzo e gestione di controlli per il login

Le ultime versioni di ASP.NET mettono a disposizione un certo numero di controlli per l’accesso ai siti web che coprono la maggior parte degli scenari possibili. Questi controlli includono: Login, LoginView, PasswordRecovery, LoginStatus, LoginName, ChangePassword e CreateUserWizard.

Descriviamo brevemente le loro caratteristiche:

Login

E’ il più semplice tra i controlli di questa categoria e supporta i più comuni scenari di login. Esso include due textbox per l’inserimento di username e password, un checkbox per il salvataggio della password sul computer locale e un pulsante per l’invio dei dati

Il controllo espone diverse proprietà attraverso cui è possibile personalizzarne l’aspetto ed è anche possibile inserire link per la gestione della registrazione degli utenti e per il recupero delle password. L’interazione con la componente di autenticazione ASP.NET è settata come impostazione predefinita ma è anche possibile gestire l’autenticazione in modo autonomo attraverso l’evento Authenticate del controllo.

LoginView

Si tratta di un controllo molto utile per gestire i contenuti da visualizzare a seconda che l’utente si sia autenticato o meno. Esso permette di visualizzare lo stato del login in base allo stato dell’utente.

PasswordRecovery

E’ uno strumento molto utile in quei siti che inviano nuovamente la password agli utenti che la dimenticano. Questo controllo memorizza i nomi degli account utente e propone una domanda di sicurezza, inviando l’email con la password se ad essa viene fornita una risposta valida.

LoginStatus

Si tratta di un link cliccando sul quale si viene reindirizzati alla pagina di login (se l’utente non è attualmente autenticato) o si effettua il logout (se l’utente risulta autenticato).

LoginName

Pemette di visualizzare il nome dell’utente correntemente autenticato.

ChangePassword

E’ uno strumento che consente agli utenti di modificare la propria password. Questa operazione è possibile se l’utente è in grado di fornire la vecchia password.

CreateUserWizard

Questo controllo consente la creazione guidata di un nuovo utente raccogliendo le informazioni necessarie allo scopo. Esso infatti richiede varie informazioni relative al nuovo utente tra cui password da impostare, indirizzo email, domanda di sicurezza e relativa risposta.

Chiaramente in tutte le immagini di esempio ho lasciato il testo in inglese proposto ma ovviamente è possibile personalizzare tutte le label e i messaggi a proprio piacimento.

Quando si crea un nuovo sito web ASP.NET genera un modello che contiene già quattro web form per la gestione delle operazioni di login

Questi web form sono Register.aspx, Login.aspx, ChangePassword.aspx e ChangePasswordSuccess.aspx. Questi form contengono già una versione predefinita di alcuni dei controlli che abbiamo appena visto. Se avviamo l’applicazione senza toccare nulla la pagina che ci comparirà è quella di login

Come già detto, quando si autentica un utente in pratica si stabilisce la sua identità. Sebbene tale informazione spesso sia molto utile un sistema diviene più sicuro quando l’autenticazione viene combinata con l’autorizzazione degli utenti, cioè stabilire con precisione cosa gli utenti possono fare all’interno delle pagine del nostro sito. Per gestire questi aspetti possiamo utilizzare lo strumento Web Site Administration Tool che abbiamo già visto in una delle lezioni precedenti.

Data binding

In ASP.NET un certo numero di controlli possiede la capacità di comprendere la forma ed il contenuto di una collezione e di generare i giusti tag per rappresentare la stessa. Tra di essi possiamo citare, ad esempio, listbox e dropdownlist.

Uno dei problemi più comuni nello sviluppo di qualsiasi software applicativo o sito web è quello di rappresentare collezioni/insiemi di elementi in opportune interfacce utente (UI, User Interface). Pensiamo ad uno dei tanti siti commerciali presenti sul web. Quando accediamo ad uno di essi se vogliamo comprare qualcosa ci troviamo solitamente a compilare una scheda, nella quale tra i vari dati solitamente è presente la nazione di appartenenza. Questo campo viene solitamente rappresentato attraverso una dropdownlist, un menù a tendina che permette di visualizzare l’elenco delle nazioni e selezionarne una.

La domanda fondamentale è: come viene popolato questo controllo? Controlli come questo (ma anche listbox per esempio) espongono la collezione Items, attraverso cui è possibile aggiungere gli elementi da elencare. Basta utilizzare il metodo Items.Add

protected void PopolaDropDownList(IList lista)
{ 
  for(int i = 0; i < lista.Count; i++) 
  { 
    this.MiaDropDownList.Items.Add(lista [i]); 
  }
}

Tuttavia come si può comprendere l’aggiunta manuale degli elementi ad un controllo non è una strada consigliabile in determinati contesti (si pensi ad esempio a insiemi di elementi da visualizzare che possono cambiare nel tempo) e per tale motivo ASP.NET include un certo numero di controlli di collegamento ai dati (data bound) capaci di prendere collezioni di elementi e di generare automaticamente i tag per la loro visualizzazione al posto nostro (il cosiddetto data binding).

Ognuno di questi controlli include opportune proprietà per il collegamento ad una sorgente dati (data source). Per data binding semplici si utilizza la proprietà DataSource, alla quale è possibile collegare qualsiasi collezione/insieme che implementi le interfacce IEnumerable, ICollection o IListSource. Dopo aver valorizzato tale proprietà è possibile è possibile invocare il metodo DataBind sulla pagina (o sul controllo) per indicare al controllo di iterare sulla collezione collegata.

I controlli che supportano tale funzionalità sono: listcontrol, checkboxlist, radiobuttonlist, dropdownlist, listbox, treeview, menu, gridview, datagrid, repeater, formview, detailsview. Chiaramente per gli scopi della presente guida non potremo approfondire le caratteristiche di ciascuno di essi e per fare ciò vi invito a consultare la documentazione ufficiale Microsoft.

Vediamo un esempio di utilizzo di alcuni di questi controlli. In Visual Studio creiamo un nuovo sito web e aggiungiamo ad esso una classe Auto dotata di due proprietà Marca e Modello che, come è facile intuire, ci servirà come una collezione di marche e modelli di auto.

Ecco di seguito la sua implementazione

public class Auto
{
  public string Marca { get; set; }
  public string Modello { get; set; }

  public Auto(string strMarca,
  string strModello)
  {
      this.Marca = strMarca;
      this.Modello = strModello;
  }
    
  public static List<Auto> CreaListaAuto()
  {
    List<Auto> lAuto = new List<Auto>();
        
    Auto sAuto;
        
    sAuto = new Auto("Lancia","Delta");
    lAuto.Add(sAuto);
        
    sAuto = new Auto("Fiat","Punto");
    lAuto.Add(sAuto);
        
    sAuto = new Auto("Audi","A4");
    lAuto.Add(sAuto);
        
    sAuto = new Auto("Mercedes","SLK");
    lAuto.Add(sAuto);
        
    sAuto = new Auto("Ferrari","F399");
    lAuto.Add(sAuto);
        
    sAuto = new Auto("Ford","Kuga");
    lAuto.Add(sAuto);
        
    return lAuto;
  }
}

Aggiungiamo un nuovo web form denominato Default.aspx al nostro progetto ed inseriamo in esso quattro dei controlli che abbiamo visto in precedenza e cioè una listbox, una dropdownlist, una radiobuttonlist e una checkboxlist

Impostiamo la proprietà AutoPostBack a true per tutti i controlli in modo che selezionando un elemento venga generato un evento di postback durante il quale l’elemento può essere interrogato. Inseriamo inoltre in una posizione qualsiasi della pagina una label che ci servirà in seguito. Adesso dobbiamo modificare la pagina per collegare la classe che restituisce la collezione di auto ai vari controlli. Per ogni controllo impostiamo la proprietà DataTextField sul campo Modello, in modo che i modelli delle auto compaiano nei vari controlli. Impostiamo poi la proprietà DataValueField sul campo Marca. Infine nell’evento Load della pagina inseriamo il seguente codice per la creazione della collezione di auto e per la relativa associazione ai vari controlli

protected void Page_Load(object sender, EventArgs e)
{
  if (!this.IsPostBack)
  {
    List<Auto> autoList = Auto.CreaListaAuto();
    this.ListBox1.DataSource = autoList;
    this.DropDownList1.DataSource = autoList;
    this.RadioButtonList1.DataSource = autoList;
    this.CheckBoxList1.DataSource = autoList;
    this.DataBind();
  }
}

Avviando l’applicazione ecco come apparirà ciascun controllo

A questo punto possiamo collegarci all’evento SelectedIndexChanged dei vari controlli per evidenziare come accedere alle informazioni relative alla marca delle auto. Siccome la procedura è simile facciamo un esempio solo per la listbox. Generiamo quindi il relativo evento SelectedIndexChanged ed inseriamo al suo interno il seguente codice

protected void ListBox1_SelectedIndexChanged(object sender, EventArgs e)
{
  this.Label1.Text = this.ListBox1.SelectedValue;
}

In questo modo avviando l’applicazione vedremo che selezionando i diversi modelli di auto la label verrà valorizzata con la corrispondente marca

Gestire le connessioni a database con ADO.NET

Nella lezione precedente abbiamo visto come legare una collezione statica (detta anche in-memory) a vari controlli lato server. Sebbene questo tipo di operazione possa essere utile in determinati contesti tuttavia spesso si presenta la necessità di legare i vari controlli a collezioni di elementi di altra origine, molto spesso provenienti da un database.

Oltre ad includere librerie di classi per lo sviluppo di applicazioni desktop (Windows Form) e per la gestione di richieste HTTP (ASP.NET), il .NET Framework include anche una libreria che supporta la connessione ad una grande varietà di database e che è denominata ADO.NET (Active Data Object .NET). Tale tecnologia si fonda su tre funzionalità principali: connessione ad un database, interrogazione di un database e gestione dei risultati.

Quando si vuole interagire con un database è necessario connettersi allo stesso. La connessione richiede l’identificazione della posizione del database ma può richiedere anche la gestione della sicurezza e di altri spetti complessi. Tutti questi elementi vengono gestiti come parte del processo di connessione ad un database. Le informazioni per la connessione vengono di solito passate sotto forma di una stringa, il cui contenuto viene utilizzato per il settaggio di vari parametri.

Mentre in passato era necessario scrivere manualmente il codice per l’accesso ad un database, tramite ADO.NET basta specificare il tipo di database a cui si desidera connettersi e automaticamente vengono impostati gli oggetti idonei a quel tipo di connessione.

Sono diversi i tipi di database supportati:

  • ODBC Data Provider
  • OLE DB Data Provider
  • OracleClient Data Provider
  • SqlClient Data Provider
  • SQL Server CE Data Provider

Questi tipi dono definiti nel già citato file machine.config

<configuration> 
<configSections> 
<section name="system.data.odbc" 
type="
System.Data.Common.DbProviderConfigurationHandler, ..."/> 
<section name="system.data.oledb"type="
System.Data.Common.DbProviderConfigurationHandler, ..."/> 
<section name="system.data.oracleclient" type="
System.Data.Common.DbProviderConfigurationHandler, ..."/> 
<section name="system.data.sqlclient" type="
System.Data.Common.DbProviderConfigurationHandler, ... "/> 
<configSections /> 
<system.data> 
<DbProviderFactories> 
<add name="Microsoft SQL Server Compact Data Provider" invariant="
System.Data.SqlServerCe.3.5" 
type=" System.Data.SqlServerCe.SqlCeProviderFactory ... " /> 
</DbProviderFactories> 
</system.data><
/configuration>>

Per creare la connessione ad un database occorre dunque utilizzare il giusto componente. Avendo a disposizione una connessione è possibile poi utilizzarlo per accedere al database. Se ad esempio sul nostro computer locale risiede un database di SQL Server denominato DB_TEST occorre inserire in una eventuale nostra applicazione la seguente stringa di connessione

<configuration> 
<connectionStrings> 
<add name="TEST" 
connectionString= "server=(local);
integrated security=sspi;database= DB_TEST "/> 
</connectionStrings>
</configuration>

A questo punto è possibile aprire la connessione e avere a disposizione il database per l’esecuzione delle operazioni che vogliamo.

La maggior parte dei database supportano il linguaggio SQL (Structured Query Language) per effettuare interrogazioni, modifiche, nuovi inserimenti e cancellazioni di dati. Tali comandi solitamente hanno una forma simile alla seguente

SELECT  *  FROM Clienti  WHERE Cognome = 'Rossi'

dove Clienti è una tabella di un database. Questo comando richiede una lista dei clienti il cui cognome è Rossi. Per ottenere questi dati all’interno di una nostra applicazione dovremmo scrivere il seguente codice

class TestDBApp
{
  static void Main()
  {
    DbProviderFactory dbProviderFactory = DbProviderFactories.GetFactory("System.Data.SqlClient");
    using (DbConnection conn = dbProviderFactory.CreateConnection())
    {
      string s = ConfigurationManager.ConnectionStrings["TEST"].ConnectionString;
      conn.ConnectionString = s;
      conn.Open();
      DbCommand cmd = conn.CreateCommand();
      cmd.CommandText = "SELECT  *  FROM Clienti  WHERE Cognome = 'Rossi'";
      DbDataReader reader = cmd.ExecuteReader();
      //Utilizzare il reader per accedere ai dati
    }
  }
}

L’esecuzione del comando (cmd) tramite il metodo ExecuteReader causa l’invio della nostra query al database. I risultati in questo caso vengono ottenuti attraverso un’istanza della classe IDatareader, ma è possibile gestirli anche tramite un’altra classe denominata DataSet.

L’interfaccia IDataReader è indicata per effettuare iterazioni sui risultati di una query. In particolare essa espone il metodo Read che scorre le righe una alla volta in modo sequenziale.Lo svantaggio è che durante la scansione non esiste la possibilità di tornare ad una riga precedente ed inoltre le righe restituite sono in sola lettura quindi non è possibile modificarne i contenuti.

L’alternativa a IDataReader è la classe DataSet, che consente la gestione di un insieme disconnesso di dati. ADO.NET è stato progettato in primo luogo per supportare applicazioni molto scalabili e uno dei problemi principali della scalabilità è il limite al numero di connessioni ad un database. I database infatti spesso hanno un limite sul numero di connessioni contemporaneamente attive e se in un determinato momento tutte quelle consentite risultano in uso le operazioni vengono rallentate. Se il numero di utenti del sistema è all’incirca uguale al numero di connessioni contemporaneamente disponibili potrebbero non verificarsi problemi rilevanti, ma se il numero di utenti è maggiore le prestazioni del sistema potrebbero risentirne drammaticamente.

Proprio per risolvere tali problemi ADO.NET mette a disposizione la classe DataSet, progettata per fornire una sorta di copia del database (o porzione di esso) utilizzato da un’applicazione. I vantaggi sono molteplici, basti pensare che all’interno di un’istanza di dataset è possibile inserire nuovi dati, aggiornare o cancellare quelli esistenti e confermare poi tutte queste operazioni che vengono eseguite in modalità disconnessa connettendosi al database per un breve periodo di tempo.

La classe DataSet include un array di oggetti DataTable, che vengono popolati tramite i DataAdapter. Questi elementi quando vengono invocati caricano i dati estratti dal database direttamente all’interno delle DataTable e successivamente è possibile lavorare su tali dati in locale, interagendo con il database solo al momento di confermare le modifiche apportate agli stessi.

Quindi utilizzando la classe DataSet abbiamo la possibilità di accedere ad ogni elemento presente in essa in modo del tutto casuale, diversamente da quanto abbiamo visto per il componente DbDataReader.

Controlli per la gestione dei dati

Dopo aver visto le modalità con cui accedere ai dati attraverso ADO.NET adesso vediamo come accedere agli stessi in modo ancora più facile e veloce. Infatti ASP.NET include diverse classi che limitano la complessità della gestione delle connessioni e del trasferimento dei dati, ossia i cosiddetti controlli DataSource.

Questi controlli rendono trasparente al programmatore tutto il meccanismo di connessione e di generazione dei comandi e tutto quello che bisogna fare è stabilire la sorgente dati (data source), puntare i controlli interessati su tale origine dati e fornire una query appropriata. Visual Studio fornisce una procedura guidata che permette di gestire facilmente questi passaggi. Una volta creato un controllo DataSource è possibile collegarlo a qualsiasi componente per la gestione di dati.

Come al solito vediamo un esempio. Aggiungiamo ad un nostro progetto un nuovo web form e dal Toolbox trasciniamo su di esso un controllo SqlDataSource. Clicchiamo su Configure Data Source nel relativo context menu

Si apre una finestra in cui è possibile selezionare un database esistente o crearne uno nuovo tramite il pulsante New Connection. Nel mio caso io seleziono il database di prova di tipo SQL Server CE denominato MioDB presente sul mio computer locale ma chiaramente è possibile selezionare qualsiasi database

Proseguiamo e in uno dei passaggi successivi specifichiamo di prelevare i dati da una tabella residente sul database (nel mio caso la tabella Amici) e selezioniamo le colonne relative (nel mio caso Id, Nome e Eta)

Nella schermata successiva è anche possibile testare la query cliccando su Test Query e infine clicchiamo su Finish. Adesso andiamo ad impostare la proprietà DataSourceMode sul valore DataReader

Inseriamo nel nostro form un controllo ListBox e spuntiamo l’opzione Enable AutoPostBack

Clicchiamo poi su Choose Data Source e nella relativa finestra di dialogo selezioniamo il controllo che abbiamo creato in precedenza specificando quale campo deve essere visualizzato nella lista e quale campo invece deve indicare il corrispondente valore

Avviando l’applicazione visualizzeremo una lista relativa ai dati della tabella che abbiamo impostato come origine dati. Il collegamento tra la listbox e l’origine dati, che abbiamo fatto tramite la finestra appena vista, avremmo potuto farlo anche scrivendo il seguente codice nell’evento Load del form

protected void Page_Load(object sender, EventArgs e)
{ 
  if (!this.IsPostBack)
  {
    this.ListBox1.DataSource = this.SqlDataSource1; 
    this.ListBox1.DataTextField = "Nome"; 
    this.ListBox1.DataValueField = "Id"; 
    this.ListBox1.DataBind();
  }
}

Questo semplice esempio serve soltanto a dare un’idea delle potenzialità degli strumenti messi a disposizione da ASP.NET per la gestione dei dati. In questo caso abbiamo utilizzato un controllo semplice, come listbox, ma esistono molti controlli più complessi per la gestione dei dati, che consentono di visualizzare gli stessi in diversi modi. Questi controlli includono: GridView, FormView, DetailsView, DataList. Chiaramente non è obiettivo di questa guida approfondire i dettagli di questi controlli e, come sempre, vi rimando alla documentazione ufficiale Microsoft per approfondire il loro funzionamento.

Interrogare i dati con LINQ

Con le ultime versioni del .NET Framework è stata introdotta una nuova tecnologia a livello di interazione con i databse denominata LINQ (Language Integrated Query). Si tratta di un insieme di estensioni del .NET Framework per effettuare rapide interrogazioni sui dati. LINQ estende la sintassi di C# e Visual Basic ma non rimpiazza le altre tecnologie per l’accesso ai dati, rappresentando un’utile alternativa alle stesse.

Questa tecnologia è denominata 'linguaggio integrato’ perchè offre la possibilità di costruire le query desiderate integrandole nella sintassi di linguaggi di programmazione ben definiti come C# e Visual Basic.

Per comprenderne le potenzialità procediamo con un esempio. Aggiungiamo un nuovo web form ad un nostro progetto e inseriamo un controllo GridView all’interno dello stesso per la visualizzazione dei dati derivanti dalla query LINQ che eseguiremo prossimamente. In quest’esempio utilizzeremo come origine dati la classe Auto che abbiamo visto qualche lezione fa (aggiungendo un altro modello della casa Ford, la Focus).

Nell’evento Load del form inseriamo il seguente codice

if (!this.IsPostBack)
{
  List<Auto> autoList = Auto.CreaListaAuto();
  GridView1.DataSource = from auto in autoList
  where
  auto.Marca.Contains("Ford") == true
  orderby auto.Marca.Length
  select auto.Modello.ToUpper();
  GridView1.DataBind();
}

Con questa sintassi stiamo chiedendo di riportare in griglia solo i modelli di auto di marca Ford e infatti eseguendo l’applicazione il risultato visualizzato sarà il seguente

Se modifichiamo il codice per visualizzare anche la marca dobbiamo scrivere

protected void Page_Load(object sender, EventArgs e)
{
  if (!this.IsPostBack)
  {
    List<Auto> autoList = Auto.CreaListaAuto();
    GridView1.DataSource = from auto in autoList
    where
    auto.Marca.Contains("Ford") == true
    orderby auto.Modello.Length
    select auto;
    GridView1.DataBind();
  }
}

e il risultato sarà il seguente

Tirando le somme il formato di una istruzione LINQ è il seguente

from <variabile in una collezione> in <collezione> 
where <criteri di selezione> 
orderby <criteri di ordinamento>
select <proprietà degli elementi selezionati>

La cosa più interessante è che con LINQ possiamo eseguire query (ma anche modificare i dati) sfruttando un modello indipendente dalle varie tipologie di fonti. E’ possibile infatti accedere a database, file di testo, file XML, array, file Excel, file di configurazione, informazioni su assembly, chiavi di registro e qualsiasi altro oggetto riconducibile ad una collezione di oggetti enumerabile.

Esistono diverse varianti di questa tecnologia, tra cui:

  • LINQ to Objects – Permette di eseguire delle query su collezioni di oggetti in memoria
  • LINQ to XML – Permette di eseguire delle operazioni su informazioni in formato XML
  • LINQ to DataSet – Permette di eseguire delle query su DataSet tipizzati
  • LINQ to SQL – Permette di rappresentare un grafo di oggetti in memoria che rappresentano gli oggetti presenti in un database SQL Server, su cui poi eseguire delle query

In particolare la tecnologia più utilizzata è LINQ to SQL per approfondire la quale vi rimando ad un articolo scritto da me qualche tempo fa che potete trovare a questa pagina.

Gestire il Session State

Lo sviluppo e la distribuzione di applicazioni web richiede il monitoraggio dello stato delle stesse in ogni momento. Uno degli stati più importanti è quello associato alla sessione (session state) e ASP.NET fornisce un grande supporto per la sua gestione.

A questo punto della guida dovrebbe essere chiaro che nella programmazione web le applicazioni sviluppate servono utenti multipli, distribuiti in una larga area, basandosi su un protocollo disconnesso (HTTP).

Quando il session state è abilitato ASP.NET crea per ogni richiesta un nuovo oggetto Session, che diventa parte del contesto ed è accessibile attraverso la pagina. A tale oggetto viene assegnato un identificatore ed esso diviene un comodo contenitore di informazioni la cui durata è superiore a quella della pagina cui si riferisce.

L’oggetto Session è un dizionario di coppie nome/valore e tramite esso è possibile associare qualsiasi oggetto ad una chiave in modo da potervi accedere quando fosse necessario, utilizzando proprio la chiave relativa.

Se per esempio volessimo memorizzare alcune informazioni relative ad un utente in un oggetto Session dovremmo scrivere qualcosa del genere

void StoreInfoInSession()
{ 
  String strInputUtente = TextBox1.Text; 
  Session["strInputUtente "] = strInputUtente;
}

e se in una successiva richiesta volessimo recuperare tale valore dovremmo scrivere

void GetInfoFromSession()
{ 
  String strInputUtente = Session["strInputUtente "] ; 
  TextBox1.Text = strInputUtente;
}

Gestire il session state in ASP.NET è estremamente conveniente, anche perchè in tale tecnologia questo tipo di oggetto può essere collocato in diversi posti: nel processo corrente, su un server di stato separato, su un database SQL Server.

Per comprendere meglio come funziona il session state vediamo un esempio in cui creeremo un sito web con una pagina che memorizzi un valore come elemento del session state. In questo modo risulterà chiara la differenza tra lo stato di una pagina durante una richiesta e le informazioni associate ad una sessione che, come detto, persistono anche in seguito alla richiesta.

Creiamo una nuova applicazione web e nel web form Default.aspx inseriamo una text box per inserire il valore da memorizzare nel session state. Aggiungiamo anche due button, uno per memorizzare i dati e uno per visualizzare lo stato

Inseriamo accanto alla text box anche una label per visualizzare il dato che richiameremo in seguito. Inseriamo una variabile di tipo string all’interno della nostra pagina e nel Page_Load impostiamo il valore di questa stringa nella nostra text box

string sessionString;

protected void Page_Load(object sender, EventArgs e)
{
  this.Label1.Text = this.sessionString;
}

Facendo doppio click sul pulsante Memorizza generiamo il corrispondente evento Click e al suo interno inseriamo il codice che recupera la stringa contenuta nella text box e la memorizza nella variabile sessionString, impostando la label accanto con lo stesso testo

protected void MemorizzaBtn_Click(object sender, EventArgs e)
{
  this.sessionString = this.TextBox1.Text;
  this.Label1.Text = this.sessionString;
}

Avviamo l’applicazione e scriviamo qualcosa nella text box e clicchiamo su Memorizza. Dovremmo vedere qualcosa del genere

Se clicchiamo sul pulsante Visualizza la label assume un valore di stringa vuota in quanto la variabile sessionString viene instanziata nuovamente (poichè la pagina viene ricreata). Questo perchè abbiamo impostato che nel Page_Load la proprietà Text della label sia impostata sul valore della variabile sessinString. Come abbiamo più volte accennato infatti, le pagine sono oggetti dalla vita molto breve, corrispondente alla durata di una richiesta e poi vengono distrutte con tutti i dati presenti in esse. Se quindi l’obiettivo è quello di memorizzare qualche dato che vada oltre la durata di una pagina l’approccio appena visto non va bene.

L’utilizzo del session state è il modo di risolvere tale problema. Per spiegare meglio il concetto aggiungiamo una seconda label al nostro web form e poniamola sotto quella già presente

Questa seconda label ci servirà per visualizzare i dati recuperati tramite l’oggetto Session. Modifichiamo l’evento MemorizzaBtn_Click in modo che il testo prelevato dalla text box venga pure memorizzato nell’oggetto Session

protected void MemorizzaBtn_Click(object sender, EventArgs e)
{
  //Memorizza il valore nella variabile locale
  this.sessionString = this.TextBox1.Text;

  //Memorizza il valore nell'oggetto Session
  this.Session["sessionString"] = this.TextBox1.Text;

  //Mostra il valore della variabile
  this.Label1.Text = this.sessionString;

  //Mostra il valore della sessione
  this.Label2.Text = (string)this.Session["sessionString"];
}

Modifichiamo anche l’evento Page_Load in modo che nella seconda label imposti la stringa recuperata dall’oggetto Session

protected void Page_Load(object sender, EventArgs e)
{
  this.Label1.Text = this.sessionString;
  this.Label2.Text =(string)this.Session["sessionString"];
}

Avviamo ora l’applicazione e scriviamo nuovamente qualcosa nella text box, cliccando poi sul pulsante Memorizza. Dovremmo vedere qualcosa del genere

Se adesso clicchiamo su Visualizza vedremo che la prima label verrà impostata su stringa vuota, mentre la seconda manterrà il valore

Mentre il valore della variabile locale si perde, poichè la pagina viene ricreata, il valore memorizzato nell’oggetto Session persiste e può essere consultato.

Per quanto riguarda la configurazione dei vari parametri per la gestione del session state vi invito a consultare la documentazione ufficiale Microsoft.

Caching dei dati

Il caching dei dati è un utile strumento per il miglioramento delle prestazioni di qualsiasi sistema software. L’idea consiste nel porre i dati più frequentemente utilizzati in un dispositivo molto performante. Infatti sebbene il tempo di accesso alle periferiche di memorizzazione di massa continui a migliorare, accedere ai dati residenti ad esempio su un hard disk è ancora un’operazione molto più lenta che accedere ad essi mentre si trovano in memoria. Rendere quindi disponibili in modo rapido i dati più utilizzati contribuisce significativamente a migliorare le prestazioni delle nostre applicazioni.

In ASP.NET la Cache è parallela alle nostre applicazioni ed è disponibile attraverso HttpContext e System.Web.UI.Page. Utilizzare la Cache è molto simile a quanto visto per l’oggetto Session, poichè è possibile accedere agli oggetti contenuti in essa tramite un indicizzatore. In aggiunta è anche possibile controllare la durata degli oggetti ed impostare dei collegamenti tra gli oggetti in cache e i dati fisici di origine.

La gestione della cache in ASP.NET è estremamente semplice e per vedere come fare procediamo con un esempio. Supponiamo di avere un metodo GetData() che effettua una connessione ad un database e restituisce una datatable

protected DataTable GetData()
{
  DataTable dt = null;
  dt = new DataTable();
  string strConnection = "Stringa di connessione al DB";
  DbProviderFactory f =
  DbProviderFactories.GetFactory("System.Data.SqlClient");
  using (DbConnection conn = f.CreateConnection())
  {
    conn.ConnectionString = strConnection;
    conn.Open();
    DbCommand command = f.CreateCommand();
    command.CommandText = "Select * from NomeTabella";
    command.Connection = conn;
    IDataReader reader = command.ExecuteReader();
    dt.Load(reader);
    reader.Close();
    conn.Close();
  }
  return dt;
}

Abbiamo anche un altro metodo BindData() che associa i dati restituiti dal metodo GetData() ad una DataList presente in un nostro web form

protected DataTable BindData()
{
  DataTable dt;
  dt = this.GetData();
  this.DataList1.DataSource = dt;
  this.DataBind();
  return dt;
}

un altro metodo che ci serve per il nostro esempio è CreaTabella che restituisce la struttura di una tabella in base ad un determinato schema

protected DataTable CreaTabella(DataTable tableSchema)
{
  DataTable tabella = new DataTable();
  foreach (DataColumn dc in tableSchema.Columns)
  {
    tabella.Columns.Add(dc.ColumnName,
    dc.DataType);
  }
  return tabella;
}

I metodi GetData() e BindData() vengono chiamati nell’evento Page_Load nel modo seguente

protected void Page_Load(object sender, EventArgs e)
{
  if (!IsPostBack)
  {
    DataTable dt = BindData();
    DataTable elementiTabella = this.CreaTabella(dt);
    Session["elementiTabella"] = elementiTabella;
  }
}

e quindi ogni volta che la pagina viene creata viene effettuata la connessione al database e vengono ricaricati i dati. In un contesto in cui le richieste provengono da pochi client la cosa potrebbe essere accettabile, per applicazioni dimensionate per soddisfare le richieste di migliaia di client questo non è accettabile. Infatti le operazioni di accesso al database dono molto onerose a livello temporale e dovrebbero essere ridotte al minimo.

A questo punto possiamo fare alcune valutazioni sulla natura dei dati gestiti dalla nostra applicazione. Domandandoci se è proprio necessario ricaricare tali dati ogni volta se essi non cambiano spesso. Se tale necessità non è presente possiamo pensare di memorizzare tali dati su un supporto che consenta un accesso agli stessi molto veloce e senza bisogno di connessioni al database (per esempio la memoria interna del computer). In questo modo l’applicazione potrebbe soddisfare molte più richieste contemporanee da parte dei client. Ovviamente se i dati trattati dalla nostra applicazione cambiassero molto spesso quest’approccio non sarebbe opportuno.

I passi per effettuare il caching dei dati sono:

  1. Verificare se un determinato dato si trova in cache
  2. Se è presente in cache utilizzarlo
  3. Se non è presente in cache connettersi al database per ottenerlo
  4. Memorizzare l’elemento appena caricato in cache per eventuali usi futuri

A questo punto andiamo a modificare i metodi che abbiamo visto nella parte iniziale della presente lezione per gestire il caching dei dati. Ecco il metodo GetData() modificato

protected DataTable GetData()
{
  DataTable dt = null;  
  dt = (DataTable)Cache["TabellaInCache"];  
  if (dt == null)
  {
    dt = new DataTable();
    string strConnection = "Stringa di connessione al DB";
    DbProviderFactory f = DbProviderFactories.GetFactory("System.Data.SqlClient");
    using (DbConnection conn = f.CreateConnection())
    {
      conn.ConnectionString = strConnection;
      conn.Open();
      DbCommand command = f.CreateCommand();
      command.CommandText = "Select * from NomeTabella";
      command.Connection = conn;
      IDataReader reader = command.ExecuteReader();
      dt.Load(reader);
      reader.Close();
      conn.Close();
    }
  }
  Cache["TabellaInCache"] = dt;
  return dt;
}

Nel nuovo metodo GetData() viene prima effettuato un controllo sull’esistenza della tabella in cache. Se la tabella non esiste if (dt == null) essa viene creata come veniva fatto in precedenza, ma se esiste la parte di connessione al database ed estrazione dei dati viene completamente bypassata. In ogni caso prima di restituire la tabella essa viene memorizzata in cache (Cache["TabellaInCache"] = dt;). Queste piccole modifiche riducono significativamente il costo del caricamento della pagina (se chiaramente è stata già creata una volta).

Chiaramente la presente lezione è volta a farvi intuire le potenzialità del caching dei dati e per approfondire le varie modalità di gestione della cache, i relativi metodi disponibili e capire quali di essi possono esservi utili di volta in volta vi invito a consultare la documentazione ufficiale Microsoft.

Diagnostica e debugging degli errori

Le architetture e le tecniche di programmazione moderne hanno reso lo sviluppo software molto più standardizzato e controllabile rispetto al passato, grazie a librerie come ASP.NET e Windows Form. Tuttavia inevitabilmente in alcuni casi le applicazioni non si comportano come previsto e in tali situazioni diviene fondamentale individuare le relativa cause.

Il punto di partenza per la diagnosi e il debugging delle applicazioni ASP.NET è il cosiddetto page tracing. La classe Page possiede una proprietà chiamate Trace e quando essa viene impostata a true si indica all’ambiente di esecuzione di inserire un resoconto dell’intero contesto di richieste e risposte alla fine del codice HTM inviato al client

Ricordiamo che una pagina è composta da un certo numero di controlli posti in una sorta di gerarchia. Una istanza della classe Page ingloba diversi controlli e i controlli stessi possono inglobare altri controlli. Il page trace include una sezione in cui è possibile consultare la composizione della pagina in termini di controlli lato server.

Se in uno dei web form di una nostra applicazione abilitiamo il page tracing nel file .aspx troveremo il relativo riferimento nella direttiva Page

Se avviamo l’applicazione vedremo le informazioni relative al page tracing alla fine dello stream HTML

Scendendo nella pagina possiamo visualizzare l’albero gerarchico dei controlli contenuti in essa

Più in basso è poi possibile consultare alcune informazioni associate alla richiesta come lo stato della sessione, lo stato dell’applicazione, le variabili lato server, ecc. Ovviamente non è immediato comprendere l’utilità di tali informazioni ma quando ci si trova a dover individuare particolari problematiche all’interno di un’applicazione web più complessa allora esse potrebbero risultare molto utili.

Volevo farvi notare che tra le varie informazioni incluse nello stream HTML vi sono anche i riferimenti alle singole istruzioni eseguite all’inerno della pagina. Se nell’evento load del web form che abbiamo utilizzato nel nostro esempio precedente scriviamo qualcosa del genere

protected void Page_Load(object sender, EventArgs e)
{
  Trace.Warn("Page_Load", "Test di annotazione chiamata");
}

avviando nuovamente l’applicazione ecco quello che vedremo

Tramite il metodo Trace.Warn è possibile dunque inserire determinati indicatori all’interno del nostro codice per individuare potenziali problemi.

Sebbene il tracing di una singola pagina sia molto utile esso presenta la controindicazione di riempire la pagina anche di informazioni tutto sommato inutili. Per aggirare questo problema è possibile applicare il tracing a livello di applicazione (application tracing), che permette di ottenere le stesse informazioni di quello a livello di pagina ma esse vengono poste in memoria e rese disponibili attraverso una pagina separata.

Per attivare l’application tracing occorre modificare il file web.config della nostra applicazione nel modo seguente

<configuration> 
<system.web> 
<trace enabled="true"/>
</system.web>
</configuration>

Fatto questo se avviamo l’applicazione e aggiungiamo all’indirizzo corrispondente il suffisso Trace.axd ecco quello che vedremo

ovvero le stesse informazioni viste in precedenza ma su una pagina separata.

Tirando le somme dunque il tracing è uno strumento molto utile per il debugging delle nostre applicazioni , soprattutto però quando esse sono già distribuite. Quando si è invece in fase di sviluppo porre messaggi da tracciare e poi eseguire le applicazioni per vedere cosa succede probabilmente non è il modo più efficiente di effettuarne il debugging.

Visual Studio fornisce un eccellente supporto al debugging ed è possibile sfruttare gli strumenti messi a disposizione dall’ambiente di sviluppo per analizzare il codice delle nostre applicazioni in fase di esecuzione linea per linea.

Per abilitare il debugging di una nostra applicazione ASP.NET occorre che il file web.config contenga la seguente direttiva

<configuration>
<system.web>
<compilation debug="true" 
targetFramework="4.0"/>
</system.web>
</configuration>

A questo punto possiamo piazzare uno a più breakpoint nei punti del nostro codice che vogliamo analizzare e avviare l’applicazione premendo F5. Vedremo che quando l’esecuzione del codice arriverà ad uno dei breakpoint essa si arresterà, consentendoci di scorrere il codice linea per linea cliccando sul tasto F10. La linea di codice in esecuzione risulta evidenziata in giallo

Cliccando su F11 in corrispondenza di un metodo si passerà ad analizzare il codice del metodo in questione. Nella fase di debugging se fermiamo il puntatore del mouse su una variabile ci viene mostrato il suo valore

Altri utili strumenti di per il debugging sono le finestre: Locals, Watch, CallStack e Threads per approfondire le funzionalità delle quali vi rimando alla documentazione ufficiale Microsoft.

Strettamente legata al debugging è la gestione degli errori e per approfondire questo argomento vi rimando ad un articolo precedentemente scritto da me che potete trovare qui.

Introduzione ad AJAX

AJAX (acronimo che sta per Asynchronous JavaSCript and XML) è una tecnologia introdotta dalla piattaforma ASP.NET con l’obiettivo di migliorare l’aspetto delle applicazioni web e l’interazione tra esse e gli utenti. Nell’ambito del software quando una tecnologia sembra essere abbastanza stabile la priorità solitamente diviene quella di migliorare l’interazione della stessa con l’utente (si parla di user’s experience).

Tali applicazioni che migliorano l’interazione con l’utente vengono denominate in gergo informatico RIA (Rich Internet Application). AJAX rappresenta proprio uno strumento attraverso cui progettare applicazioni RIA.

Il primo motivo che ha portato alla nascita di AJAX è stato quello di migliorare le fasi HTTP di GET/POST delle pagine web. Infatti sebbene lo standard HTTP è funzionale e ormai ben conosciuto dagli sviluppatori esso presenta delle limitazioni, la prima delle quali è che l’utente costretto ad aspettare per un certo periodo di tempo mentre le pagine si aggiornano. AJAX introduce meccanismi che evitano (o riducono) questa attesa.

Pensiamo a come funziona il protocollo HTTP: quando si effettua una richiesta il browser invia la stessa la server e non è possibile fare altro finchè questo processo non giunge a termine. In pratica dunque si invia la richiesta e si attende, mentre l’indicatore posto in basso nel browser mostra il livello di completamento dell’operazione e solo quando il controllo torna al browser è possibile ricominciare ad utilizzare l’applicazione.

L’applicazione è dunque inutilizzabile finchè la richiesta non ritorna e in molti casi la finestra del browser diventa completamente bianca. La soluzione proposta da AJAX è quella di introdurre qualcosa che gestisca la richiesta asincronamente in modo che il browser sia più reattivo nell’interazione con l’utente non bloccando l’intera pagina ma solo la porzione necessaria.

Una delle novità che AJAX ha apportato alla programmazione web è l’introduzione di nuove librerie lato client per facilitare le chiamate asincrone al server. Altra novità è l’introduzione di nuovi componenti lato server per supportare queste nuove chiamate asincrone provenienti dai client.

La seguente immagine, tratta dal sito Microsoft, riassume concettualmente l’universo AJAX

A prima vista AJAX sembra introdurre una maggiore complessità nelle modalità di sviluppo delle applicazioni web ma in realtà questa tecnologia porta alcuni fondamentali vantaggi:

  • Eliminazione dei tempi morti in attesa della risposta inviata al server tramite il protocollo HTTP
  • Introduzione di elementi grafici solitamente presenti in applicazioni desktop e di finestre di tipo pop-up molto utili per l’interazione con gli utenti
  • Introduzione dell’aggiornamento parziale della pagine, solo nelle sezioni interessate
  • Supporto esteso a tutti i browser più diffusi e non soltanto a Internet Explorer
  • Introduzione del concetto di extender control, una nuova tipologia di controlli che aggiungono un nuovo aspetto e nuove funzionalità ai canonici controlli lato client
  • Miglioramento dei servizi di autenticazione, profili e personalizzazione

La maggior parte del supporto per AJAX fornito da ASP.NET consiste in un insieme di controlli lato server responsabili del rendering delle pagine web nel nuovo stile introdotto da questa nuova tecnologia. In generale il lavoro di un controllo lato server è quello di produrre un output che collochi gli elementi HTML in modo che essi compaiano correttamente nel browser e i controlli stile AJAX si comportano allo stesso modo.

I controlli di tipo AJAX più frequentemente utilizzati sono:

  • ScriptManager – Gestisce gli script della pagina. La sua prima azione è quella di registrare la AJAX Library con la pagina in modo che gli script lato client possano utilizzarne le relative estensioni. Questo controllo consente inoltre il rendering parziale delle pagine.
  • ScriptManagerProxy – Gli script su una pagina web spesso richiedono una gestione speciale sul modo in cui il server li deve eseguire. Tipicamente viene utilizzato un controllo ScriptManager per organizzare gli script a livello di pagina mentre altri componenti nidificati (come i controlli utente) richiedono il controllo ScriptManagerProxy per gestire pagine e servizi dotati già di un controllo ScriptManager. Un esempio di questa situazione sono le master page che tipicamente contengono un controllo ScriptManager. ASP.NET genera un’eccezione se se una seconda istanza di tale controllo viene individuata in una data pagina e pertanto le pagine di contenuti che utilizzano quelle determinate master page devono utilizzare obbligatoriamente il controllo ScriptManagerProxy.
  • UpdatePanel – Questo controllo consente l’aggiornamento parziale delle pagine.
  • UpdateProgress – Mostra le informazioni di stato sugli aggiornamenti parziali delle pagine che avvengono tramite il controllo UpdatePanel.
  • Timer – Questo controllo genera dei postback ad intervalli predefiniti. Esso viene utilizzato in particolare in stretta relazione con il controllo UpdatePanel per effettuare aggiornamenti parziali periodici di determinate sezioni delle pagine.

Il supporto lato client di AJAX si incentra invece su un insieme di librerie JavaScript che includono i seguenti livelli:

  • Livello di compatibilità dei browser che assicura la compatibilità delle funzioni AJAX sui browser più diffusi;
  • Nucleo di servizi che estendono il tradizionale ambiente JavaScript introducendo classi, namespace, gestori di eventi, tipi di dati e serializzazione di oggetti;
  • Libreria base di classi lato client che include diversi componenti, come quello per la gestione delle stringhe e per quello per l’estensione della gestione degli errori;
  • Livello di rete che gestisce la comunicazione tra i servizi web e e le applicazioni. Tale livello si occupa pure della gestione delle chiamate asincrone;

Molto utile è l’ASP.NET Control Toolkit che consiste in una collezione di componenti (e di esempi che mostrano come utilizzare gli stessi) che consentono l’utilizzo delle funzioni AJAX. Questo Toolkit fornisce inoltre un kit di sviluppo software per creare controlli personalizzati ed è scaricabile dal sito web ufficiale ASP.NET AJAX. Esso non è incluso in Visual Studio 2010 e deve essere scaricato separatamente. Per tutti i dettagli potete consultare a questa pagina.

E’ possibile scaricare i file binari o il codice sorgente. Se non vi interessa il codice sorgente per utilizzare questo componente è sufficiente aggiungere un riferimento all’assembly AjaxControlToolkit.dll ai vostri progetti.

Oltre ad AJAX negli ultimi anni sono stati introdotte varie altre utili tecnologie come Silverlight, WPF, WCF, che non saranno trattate nella presente guida poichè sono state già presentate con alcuni articoli specifici che potete trovare nella sezione articoli ASP.NET del nostro sito.

Utilizzo di AJAX

Dopo aver introdotto AJAX vediamo un esempio volto a fare intuire le potenzialità di questa innovativa tecnologia. Creeremo una semplice applicazione con una pagina di contenuto in cui inseriremo un UpdatePanel. Inseriremo poi nell apagina due label che mostreranno la data e l’ora in cui la pagina viene caricata ma porremo una label all’interno dell’ UpdatePanel e l’altra all’esterno in modo da vedere come funziona l’aggiornamento parziale della pagina.

Creiamo dunque un nuovo sito web e aggiungiamo al form Default.aspx un controllo ScriptManager (posto nella tab AJAX Extensions del Toolbox), necessario per la gestione dei controlli AJAX inseriti nel form. Convenzionalmente tale controllo viene posto al di fuori del tag DIV che Visual Studio crea automaticamente. Dopo l’inserimento di questo controllo nella nostra pagina dovremmo avere una situazione simile alla seguente

Inseriamo ora una label nel nostro form e denominiamola LabelDataOraLoad. Inseriamo anche un button

Apriamo il file default.aspx.cs e modifichiamo L’ebento Page_Load in modo che la label visualizzi la data e l’ora correnti

protected void Page_Load(object sender, EventArgs e)
{
  this.LabelDataOraLoad.Text = DateTime.Now.ToString();
}

Avviamo l’applicazione e generiamo alcuni postback, cliccando più volte sul button. Quello che osserviamo è che i valori riportati cambiano ad ogni pressione del button.

A questo punto aggiungiamo un controllo UpdatePanel alla pagina e poniamo una seconda label denominata LabelDataOraUpdate all’interno di tale controllo

Anche per questa label modifichiamo l’evento Page_Load in modo che essa visualizzi la data e l’ora correnti

protected void Page_Load(object sender, EventArgs e)
{
  this.LabelDataOraLoad.Text = DateTime.Now.ToString();
  this.LabelDataOraUpdate.Text = DateTime.Now.ToString();
}

Avviamo l’applicazione e generiamo alcuni postback come in precedenza. Vediamo che le label si comportano alla stessa maniera, aggiornandosi ad ogni click

Questo perchè sebbene la seconda label sia all’interno dell’UpdatePanel l’azione che causa i postback avviene al di fuori di questo controllo. A questo punto eliminiamo spostiamo il Button all’interno dell’UpdatePanel. Se guardiamo il file default.aspx vediamo che il button viene posto all’interno dei tag relativi al panel

Se a questo punto avviamo l’applicazione vediamo che cliccando sul Button soltanto la label contenuta nell’UpdatePanel viene aggiornata mentre l’altra rimane impostata sul valore relativo al primo caricamento della pagina

Questo è proprio il processo denominato aggiornamento parziale della paginaperchè soltanto una arte della pagina viene aggiornata in risposta ad una determinata azione (il click del Button).

Questo chiaramente è solo un piccolo esempio che mostra le potenzialità di AJAX e vi invito ad approfondire tramite la documentazione ufficiale Microsoft le interessanti funzionalità di altri controlli come Timer, UpdateProgress, AutoCompleteExtender, ecc.

Distribuzione di applicazioni ASP.NET

Nel momento in cui mettiamo in pratica le nostre conoscenze di ASP.NET e sviluppiamo un’applicazione web il passo successivo è quello relativo alla distribuzione (in inglese deploy) della stessa. Fortunatamente ancora una volta anche per questo scopo ci viene in aiuto Visual Studio.

Come abbiamo accennato all’inizio della guida esistono diversi modelli di siti web che è possibile utilizzare per sviluppare e distribuire le nostre applicazioni su varie piattaforme

  • HTTP – Per questo tipo di siti Visual Studio crea una directory virtuale sotto IIS e utilizza IIS per intercettare le richieste effettuate in fase di sviluppo. In questo modello il file relativo alla soluzione (di estensione .sln) risiede in una directory specificata nelle impostazioni del progetto in Visual Studio. Il codice sorgente viene viene invece memorizzato nella directory virtuale di IIS (…Inetpubwwwroot). Sebbene questo non sia il modello di sviluppo più indicato per molte organizzazioni, in alcuni casi (come lo sviluppo di siti da parte di singoli programmatori) esso può essere indicato.
  • FTP – L’opzione per la creazione si siti web FTP è stata introdotta nella versione 2005 di Visual Studio per quei progetti che si desidera gestire da remoto tramite un server FTP. Per esempio questa opzione è consigliabile se si utilizza un servizio di hosting remoto per il proprio sito web. In questo modo si dispone di un semplice meccanismo per trasferire file dall’ambiente di sviluppo all’ambiente che ospita il sito. Per questo tipo di sito Visul Studio può connettersi ad un server FTP sul quale occorre disporre dei privilegi di lettura e scrittura sulla directory interessata. Se si dispone di tali permessi tramite Visual Studio è possibile gestire i contenuti del server FTP.
  • File System – Questa opzione è quella più orientata alle esigenze degli sviluppatori. Utilizzando tale modello si sfrutta il server web integrato in Visual Studio stesso per eseguire e testare l’applicazione ed è possibile collocare la relativa directory in qualsiasi locazione del file system locale o anche su una cartella condivisa di un altro computer. Questo modello rappresenta una scelta obbligata se non si dispone dell’accesso a IIS o non si dispone dei privilegi amministrativi sul sistema su cui si sta sviluppando l’applicazione. In questo modo il sito gira localmente sul sistema ma in modo indipendente da IIS ed è possibile sviluppare e testare il sito sul file system. Successivamente quando il sito è pronto basta creare una directory virtuale su IIS e puntare la stessa sulla locazione del file system in cui si trova il sito.

Per molti programmatori la distribuzione di un’applicazione è qualcosa a cui pensare alla fine del processo di sviluppo ed è un’attività completamente separata dalle altre. Invece la distribuzione di un’applicazione web è un’attività da tenere in considerazione fin dall’inizio del processo di sviluppo poichè, specialmente dopo l’avvento del cloud computing, si potrebbe non disporre dell’accesso ai server sui quali l’applicazione stessa dovrà girare.

Per tale motivo Visual Studio include diverse nuove caratteristiche che rendono la distribuzione di un’applicazione un’operazione molto più gestibile rispetto al passato.

Tra queste nuove caratteristiche vi sono:

  • Web packaging
  • Gestione dei file web.config per la distribuzione
  • Distribuzione database
  • Modalità di pubblicazione One-Click

Nelle versioni precedenti dell’ambiente di sviluppo che non includevano tali caratteristiche solitamente si creava un pacchetto di installazione per la distribuzione delle applicazioni web. Sebbene creare un pacchetto di questo tipo sia preferibile alla semplice copia di file su un server web, il meccanismo dei pacchetti di installazione non poteva tenere conto di alcune cose come per esempio il fatto che lo schema di un database potrebbe cambiare in una delle distribuzioni di un’applicazione successive alla prima.

La nuova caratteristica web packaging permette proprio di aggirare tali problemi. Tramite tale strumento è possibile creare un file compresso o una cartella contenente tutto il necessario per la distribuzione del progetto su un server web.

Un web package include:

  • Contenuti (web form, controlli, file HTML, ecc.)
  • Database, schemi e dati di SQL Server (se l’applicazione li prevede)
  • Impostazioni relative ad IIS
  • Altri elementi necessari a supporto del progetto (componenti da installare nella global assembly cache, certificati di sicurezza, informazioni sulle impostazioni di voci di registro, ecc.)

Una volta creato un web package è possibile copiarlo su un server ed installarlo manualmente (utilizzando l’IIS Manager) o installarlo utilizzando opportuni comandi. In ogni caso come al solito il modo migliore per comprendere il tutto è quello di procedere con un esempio. Pertanto creiamo una nuova applicazione web

e denominiamola WebApplicationDeploy.

Viene creata la canonica applicazione di partenza ASP.NET che contiene, tra le altre cose, il web form Default.aspx

Supponendo che la nostra applicazione sia completa clicchiamo con il tasto destro del mouse sulla soluzione e scegliamo l’opzione Package/Publish Settings

Togliamo il segno di spunta sull’opzione Create deployment package as zip file (perchè vogliamo che i file vengano posti in una directory e non in un file compresso) e salviamo

Clicchiamo di nuovo con il tasto destro del mouse sulla soluzione e scegliamo l’opzione Build Deployment Package

In questo modo viene creata nella directory del progetto (sotto objDebugPackagePackageTemp) tutto il necessario per la distribuzione dell’applicazione

A questo punto basta copiare tutti questi elementi in una directory da utilizzare come directory virtuale del nostro sito ed impostare IIS come abbiamo visto all’inizio della guida per permettere l’accesso al sito da parte degli utenti.

Pubblicitร 

Leggi anche...

Accorgimenti per la scrittura di codice efficiente in C#

Nella scrittura del codice delle proprie applicazioni uno sviluppatore...

Visual Studio 2012: l’ambiente di sviluppo di casa Microsoft

Visual Studio 2012 è l'ultima versione dell'ambiente di sviluppo...

Utilizzo del controllo DataGridView

Il controllo DataGridView è uno di quelli disponibili in...

Algoritmi di ordinamento in C#

L'ordinamento di una lista di oggetti è uno dei...

Guida Visual Studio 2008

L'uscita di Visual Studio 2005 ha rappresentato la più...

Sviluppare web app con ASP.Net

Da qualche anno Microsoft ha lanciato sul mercato una...
Pubblicitร