ASP.NET: I file di configurazione


Corso ASP.NET: dodicesima puntata

Esempio funzionante | Sorgente | Scarica il sorgente (zip)

Chi di voi ha realizzato in passato vere e proprie applicazioni con Asp, si è certamente scontrato con la difficoltà di prendere il progetto sviluppato in locale e portarlo in produzione. Le differenze di configurazione tra i server (in particolare Iis) dà a volte risultati imprevisti, che magari si manifestano quando il sito è già stato avviato.

ASP.NET risolve questa problematica gestendo le configurazioni dei server e degli applicativi utilizzando due file in formato Xml:

  • web.config – può essere utilizzato per ogni applicazione e definisce la configurazione e le politiche di sicurezza delle pagine componenti l’applicazione
  • machine.config – è un unico file che contiene la configurazione comune a tutto il server

Con ASP.NET viene anche ridiscusso il ruolo di Global.asa (Global.asax da questa versione), che non si occupa più di contenere informazioni sulla configurazione dell’applicazione, ma contiene piuttosto parti di codice comune.

Web.config

Web.config facilita la sincronizzazione tra ambiente di prova e ambiente di produzione. Può contenere:

  • variabili comuni a tutte le applicazioni
  • configurazioni per le sessioni
  • opzioni per la gestione degli errori
  • informazioni per la sicurezza

Vediamo la configurazione in azione con un semplice esempio: il reindirizzamento ad una pagina in caso di errore.

Abbiamo creato una semplice pagina che genera un errore (è dichiarato un DataSet ma non sono importati i namespace di ADO.NET).

Il semplice file di configurazione, che ospitiamo nella stessa cartella della pagina, ha una forma del tipo:

  1 <?xml version="1.0" encoding="utf-8" ?>
  2 <configuration>
  3  <appSettings>
  4  <add key="ConnectionString" value="Provider=SQLOLEDB.1;data source=antoniov;initial catalog=Biblioteca;uid=anon;pwd=;" />
  5  </appSettings>
  6  <system.web>
  7  <customErrors mode="On" defaultRedirect="errorpage.aspx" />
  8  <sessionState mode="Off" />
  9  </system.web>
 10 </configuration>

Nell’esempio sono presenti due elementi di interesse:

  • è aggiunta una chiave che permette di centralizzare l’uso della stringa di connessione utilizzata per connettersi ad un database
  • il tag customErrors definisce la pagina da richiamare in caso di errore

Per accedere alla chiave da una pagina aspx è sufficiente utilizzare una sintassi del tipo ConfigurationSettings.AppSettings(“ConnectionString”)

Global.asax

Abbiamo detto che il file global.asax da questa versione non ospiterà più elementi di configurazione: questa eredità viene presa da web.config.

Global.asax è ora un “contenitore” di codice comune ad un’applicazione web. Viene impiegato tra l’altro per:

  • importare dei namespace a livello di applicazione per non doverli dichiarare in ogni pagina
  • eseguire operazioni all’avvio e al termine delle sessioni e dell’applicazione (come già accadeva in parte con Asp)
  • eseguire del codice al verificarsi di una condizione di errore

Nel prossimo esempio vediamo proprio come è possibile gestire una condizione di errore salvando un log nel registro degli eventi.

La struttura di global.asax è la seguente:

  1 <%@ Import Namespace="System.Diagnostics" %>
  2 
  3 <script language="VB" runat="server">
  4 
  5 Sub Application_Error(objSender as Object, objArgs as EventArgs)
  6 
  7   Dim strLogName As String = "Errori Web"
  8   Dim strMessage As String = "Url " & Request.Path & " Errore: " & Server.GetLastError.ToString
  9 
 10   If (Not EventLog.SourceExists(strLogName)) Then
 11     EventLog.CreateEventSource(strLogName, strLogName)
 12   End if
 13 
 14   Dim ELLog as New EventLog
 15   ELLog.Source = strLogName
 16   ELLog.WriteEntry(strMessage, EventLogEntryType.Error)
 17   
 18 End Sub
 19 
 20 </script>

Al verificarsi di un errore (se questo non viene già intercettato dal codice presente nella pagina), viene scatenato l’evento Application_Error. A questo punto viene verificata la presenza di un log “Errori Web” che viene eventualmente creato e popolato con la descrizione dell’errore verificatosi.

L'event viewer con gli errori scatenati

Xhtml e l’accessibilità web – Amici per la pelle

È vero: all’inizio non è facile capire perché valga la pena utilizzare lo standard Xhtml per la costruzione delle pagine.

Quello su cui molti si interrogano è la reale necessità di passare da un linguaggio (Html) ad un altro che gli somiglia e sembra aggiungere poche (forse nessuna) funzionalità di rilievo.

A questo si aggiungono i dubbi sui costi di aggiornamento e addestramento per un sito che possa definirsi accessibile: utilizzo dei tag e degli attributi corretti, interpretazione e applicazione delle linee guida.

I due concetti possono sembrare tra loro distanti, ma hanno invece diversi punti in comune.

Potremmo dirvi (anzi, l’abbiamo già fatto in un precedente articolo) che Xhtml è lo standard del futuro, che aiuta a separare lo strato di presentazione dal contenuto, che può essere esteso con la creazione di moduli, ecc.

Quello che però vogliamo presentare oggi è un esempio legato da un lato al tema dell’accessibilità web, dall’altro al costo dei contenuti.

In “Il vero costo dell’accessibilità web” abbiamo detto che i contenuti di un sito costano, e costano molto. Per questo motivo, è necessario costruirli efficacemente.

Di conseguenza, perchè il contenuto di un sito sia costruito in modo efficace, è necessario che si verifichino queste condizioni:

  • dev’essere scritto “correttamente”
  • deve rispondere alle domande degli utenti
  • dev’essere facilmente ricercabile
  • dev’essere facilmente indicizzabile
  • dev’essere trasformabile

Per i primi due punti, come sviluppatori e designer, c’è ben poco da fare: il contenuto va scritto da persone competenti.

Il nostro ruolo è quello di garantire (insieme a chi edita i testi) che il contenuto non rimanga sepolto nei meandri del sito, ma che possa essere trovato anche quando non è strillato ai quattro venti dalla Homepage.

Non solo, il contenuto va opportunamente categorizzato, perché chi usa il sito probabilmente ha un problema da risolvere, alla cui soluzione arriva procedendo dalla Homepage alle sezione e alle sottosezioni.

Ma il contenuto dev’essere anche trasformabile: quello che oggi è una pagina web domani potrebbe trasformarsi in un articolo cartaceo o in un documento Pdf. Per non parlare di visualizzazione su cellulari, Pda, ecc. Riscrivere una versione ad hoc per queste esigenze introdurrebbe degli altri costi.

Se lo standard Xhtml viene usato con “accortezza”, donerete al vostro contenuto il segreto dell’eterna giovinezza, perché potete passare da una versione all’altra senza riscrivere il contenuto. Ma non solo: lo fate con estrema semplicità, utilizzando lo standard Xsl.

Vediamolo con un esempio.

Convertire documenti Xhtml

Partiamo da una semplice (quasi banale) pagina che contiene un piccolo articolo. Ecco come è visualizzata:

Categoria: Sviluppo web

Come abbiamo già visto la scorsa puntata, con il solo Html non è possibile realizzare siti dinamici.

Per creare applicativi lato server è possibile ricorrere all’uso dei seguenti linguaggi di scripting (cfr. il manuale cartaceo a pag. 52):

Per costruire la pagina sono stati impiegati i tag e gli attributi che migliorano l’accessibilità e l’usabilità del documento: acronym, abbr, title, lang, ecc. Il sorgente è il seguente:

  1 <html lang="it" xmlns="http://www.w3.org/1999/xhtml">
  2   <head>
  3     <title>Xhtml e i tag accessibili</title>
  4   </head>
  5   <body>
  6     <p>Categoria: <span id="categoria"><strong>Sviluppo <span lang="en">web</span></strong></span></p>
  7     <p>Come abbiamo gi&agrave; visto la <a href="http://www.foo.com/percorso1" title="Puntata precedente: sviluppare per il web">scorsa puntata</a>, con il solo <acronym lang="en" title="HyperText Markup Language">Html</acronym> non &egrave; possibile realizzare siti dinamici.</p>
  8     <p>Per creare applicativi lato <span lang="en">server</span> &egrave; possibile ricorrere all’uso dei seguenti linguaggi di <span lang="en">scripting</span> (<abbr title="confronta">cfr.</abbr> il manuale cartaceo a <abbr title="pagina">pag.</abbr> 52):</p>
  9     <ul>
 10       <li>
 11         <acronym lang="en" title="Active Server Pages">Asp</acronym> di <a href="http://www.microsoft.com" title="Sito web di Microsoft Corporation"><span lang="en">Microsoft</span></a>, su <acronym lang="en" title="Internet Information Services">Iis</acronym>
 12       </li>
 13       <li>
 14         <acronym lang="en" title="Java Server Pages">Jsp</acronym> di <span lang="en"><a href="http://www.sun.com" title="Sito web si Sun Microsystem">Sun</a></span>
 15       </li>
 16       <li>
 17         <acronym lang="en" title="Hypertext Preprocessor">Php</acronym>
 18       </li>
 19     </ul>
 20   </body>
 21 </html>

Come vedete, il testo è arricchito da informazioni aggiuntive che ne migliorano l’accessibilità.

I vantaggi però non si fermano all’accessibilità: il fatto che il documento sia standard Xhtml consente la realizzazione, tramite Xsl, di opportuni fogli di trasformazione che consentono di tradurre il documento in un altro formato.

Un esempio di risultato (forse il più semplice tra gli infiniti disponibili) è il seguente:

Categoria: Sviluppo web

Come abbiamo già visto la scorsa puntata, con il solo Html non è possibile realizzare siti dinamici.

Per creare applicativi lato server
è possibile ricorrere all’uso dei seguenti linguaggi di scripting (cfr. il manuale cartaceo a pag. 52):


Link nella pagina
Acronimi
Abbreviazioni
  • cfr.: confronta
  • pag.: pagina
Termini stranieri
Categoria
  • Sviluppo web

Come potete vedere, l’articolo è stato stravolto: sono stati estratti e separati gli acronimi, le abbreviazioni, le parole in lingua straniera e i link.

Sono anche state aggiunte alcune funzionalità:

  • se selezionato un acronimo vi collegate a Google, dove troverete una definizione estesa del termine
  • se selezionate un termine straniero interrogare invece Babylon, che cercherà di trovare il corrispettivo italiano
  • compare un elenco dei link e il testo di accompagnamento è l’attributo title del link

Abbiamo ricavato molte informazioni precise da un testo davvero modesto.

Inoltre, il tempo necessario per la costruzione del foglio Xsl per la trasformazione ha richiesto non più di un’ora ed è applicabile a qualsiasi documento Xhtml.

Usare lo standard Xhtml insieme ai tag di solito ignorati (quelli che migliorano
l’accessibilità), vi apre quindi molti scenari:

  • possibilità di realizzare una copia per il mondo cartaceo
  • conversioni per telefoni e Pda
  • costruzione automatica di indici e tabelle con le abbreviazioni
  • elenco dei link presenti nella pagina
  • isolamento dei termini stranieri
  • categorizzazione dei contenuti della pagina (per parole d’ordine, tipologia, ecc.)

Possibili obiezioni

Come tutte le metologie, sono naturali alcune critiche al metodo sopra illustrato. Cerchiamo di prevederle insieme.

Non è meglio usare l’Xml come lingua franca per poi trasformare i documenti?

Senza dubbio l’Xml è il candidato principe alle trasformazioni Xml.

In questa sede stiamo però parlando di contenuti, che come tali saranno inseriti da un editor di competenze tecniche limitate.

È sicuramente possibile utilizzare l’Xml per categorizzare un documento la cui struttura è fissa (titolo, sommario, categorie, data, ecc.), più difficile se i dati sono “semistrutturati“.

Poiché ogni documento ha una struttura diversa dagli altri (per numero e posizione degli acronimi, dei collegamenti, delle parole straniere), l’editor ha più controllo con lo standard Xhtml, di cui riesce agevolmente ad avere un’anteprima su browser.

Ma un documento Xhtml è una specializzazione di documento Xml, per cui sarà possibile trasformarlo senza rinunciare ad alcuna caratteristica.

Non è eccessivo il costo per produrre contenuti così ricchi di informazioni?

Il costo c’è e non è esiguo. Non solo: mentre scrivere Html è ormai alla portata di tutti, diventa ora importante che i documenti siano sintatticamente e semanticamente corretti.

Ma tanto più il business dipende dai contenuti (siano questi articoli, documenti, listini), tanto maggiore sarà il risparmio futuro.

È possibile trasformare un documento anche partendo dall’Html. Perché devo usare Xhtml?

Perché è estremamente più semplice.

Il formato Xml di per sé non rappresenterebbe niente di eccezionale se lo sviluppo di procedure di interrogazione e trasformazione fosse complesso e costoso.

In realtà, i vincoli di cui bisogna tener conto nella scrittura di un documento Xml (è case sensitive, ha un solo nodo padre, tutti i tag devono essere chiusi), fa si che i parser per l’interrogazione e la trasformazione siano molto efficienti e semplici da utilizzare.

Conclusione

Il contenuto incide in larga misura sui costi di realizzazione di un sito accessibile. Vale perciò la pena di realizzarlo secondo lo standard Xhtml ed utilizzando tutti i tag che arricchiscono il testo di informazioni.

In questo modo è possibile facilitare la ricerca e la memorizzazione dei documenti, ma anche le conversioni per altri media e formati e per future versioni del sito.

ASP.NET e Xml – Codice sorgente dell’esempio

Sorgenti: LeggiXml.aspx

Scarica i sorgenti: aspnet11.zip

Articolo a cui si riferisce il codice: ASP.NET e Xml

LeggiXml.aspx

  1 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
  2 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
  3 
  4 <%@ Page Language="VB" Debug="True" %>
  5 
  6 <%@ Import Namespace="System.Data" %>
  7 <%@ Import Namespace="System.Data.OleDb" %>
  8 
  9 <%@ Register TagPrefix="ANet" TagName="Footer" Src="includes/footer.ascx"%>
 10 
 11 <!
 12 # nome: XMLLeggi.aspx
 13 # scritto da: Antonio Volpon
 14 # data creazione: 23 Novembre 2001
 15 # ultima modifica: 23 Novembre 2001
 16 # copyright: Antonio Volpon
 17 >
 18 
 19 <script language="vb" runat="server">
 20 
 21 Sub CaricaXml()
 22   
 23   Dim objDataSet As New DataSet()
 24   Dim objTableLibro As DataTable
 25   Dim objTableView As DataView
 26   
 27   Dim strUrlPath As String
 28   Dim strLocPath As String
 29   
 30   strUrlPath = Left(Request.Path,InStrRev(Request.FilePath,"/")) & "Xml/"
 31   
 32   strLocPath = Request.MapPath(strUrlPath)
 33   
 34   objDataSet.ReadXmlSchema(strLocPath & "XmlSchema.xml")
 35 
 36   risposta.innerHtml += "Caricato il file <a target=‘_blank’ href=’"& strUrlPath & "XmlSchema.xml’>" & strUrlPath & "XmlSchema.xml</a><br>"
 37 
 38   objDataSet.ReadXml(strLocPath & "XmlDocument.xml")
 39   
 40   risposta.innerHtml += "Caricato il file <a target=‘_blank’ href=’"& strUrlPath & "XmlDocument.xml’>" & strUrlPath & "XmlDocument.xml</a><br>"
 41   
 42   objTableLibro = objDataSet.Tables("Libro")
 43     
 44   objTableView = objTableLibro.DefaultView
 45   
 46   libri.DataSource = objTableView
 47   libri.DataBind()
 48   
 49 End Sub
 50 
 51 Sub Change_Index(objSender As Object, objArgs As DataGridPageChangedEventArgs)
 52 
 53   libri.CurrentPageIndex = objArgs.NewPageIndex
 54   CaricaXml()  
 55   
 56 End Sub
 57   
 58 Sub Page_Load()
 59 
 60   If Not Page.IsPostBack() Then
 61 
 62     CaricaXml()          
 63   
 64   End If
 65 
 66 End Sub
 67 
 68 </script>
 69 
 70 <html>
 71 
 72   <head>
 73     <link rel="stylesheet" href="css/aspnet.css" type="text/css">
 74     </link>
 75     <title>Da XML a DataSet</title>    
 76   </head>
 77   
 78   <body>
 79     <div class="titolo">
 80       Da XML a DataSet
 81     </div>
 82     
 83     <hr noshade="true" size="1" width="100%">  
 84     
 85     <center>
 86     
 87     <form runat="server">
 88     
 89  <asp:DataGrid id="libri" runat="server"
 90  AutoGenerateColumns="False"
 91  HeaderStyle-BackColor="#CCCCCC"
 92  HeaderStyle-HorizontalAlign="center"
 93  Width="80%"
 94  AllowPaging="True"
 95  PageSize="10"
 96  PagerStyle-HorizontalAlign="Right"
 97  PagerStyle-Mode="NumericPages"
 98  OnPageIndexChanged="Change_Index"
 99  AllowSorting="True">

100      
101       <SelectedItemStyle BackColor="Yellow"></SelectedItemStyle>
102       <AlternatingItemStyle BackColor="LightGreen"></AlternatingItemStyle>     
103       <Columns>
104 
105         <asp:TemplateColumn HeaderText="Seleziona" ItemStyle-HorizontalAlign="Center">
106           <ItemTemplate>
107             <asp:Button CommandName="Select" Text="x" runat="server" />
108           </ItemTemplate>
109         </asp:TemplateColumn>
110   
111         <asp:BoundColumn DataField="IdLibro" HeaderText="Id" ItemStyle-HorizontalAlign="Left" SortExpression="IdLibro" ReadOnly="True"/>
112         
113         <asp:TemplateColumn HeaderText="Titolo" ItemStyle-HorizontalAlign="Left" SortExpression="Titolo">
114           <ItemTemplate>
115             <%# Container.DataItem("Titolo")%>  
116           </ItemTemplate>
117           <EditItemTemplate>
118             <asp:TextBox id="titolo" text=’<%# Container.DataItem("Titolo") %>‘ runat="server"/>
119             <asp:RequiredFieldValidator ControlToValidate="titolo" Display="Dynamic" runat="server" >
120               Valore obbligatorio
121             </asp:RequiredFieldValidator>            
122           </EditItemTemplate>          
123         </asp:TemplateColumn>
124         
125         <asp:BoundColumn DataField="EdizioneAnno" HeaderText="Anno" ItemStyle-HorizontalAlign="Left" SortExpression="EdizioneAnno" />
126         <asp:BoundColumn DataField="Collana" HeaderText="Collana" ItemStyle-HorizontalAlign="Left" SortExpression="Collana" />
127         
128       </Columns>
129 
130    </asp:DataGrid>
131     
132     <div id="risposta" class="txt" runat="server" EnableViewState="false"></div>
133 
134     </form>
135 
136     </center>
137 
138  <ANet:Footer id="Menu" runat="server" />
139     
140   </body>
141   
142 </html>