[ASP.NET 2.0] Gestione di un contatore accessi

Premessa
Questo articolo riprende gli argomenti trattati nell’articolo “VB 2005: connessione a database con ADO.NET 2.0“, ma da un altro punto di vista. Infatti qui si parlerà ancora di connessione a database con ADO.NET 2.0 e di stringhe di connessione, ma l’ambito di sviluppo è questa volta il web con ASP.NET 2.0.
Per rendere la spiegazione più interessante, inoltre, si mostrerà anche come è possibile creare un contatore degli accessi in tre modi diversi:

  • 1. con un file di testo (quindi senza database),
  • 2. con un database Access e stringa di connessione inserita nel codice e
  • 3. con un database Access, ma con la stringa di connessione inserita nel file di configurazione del sito.

Esempio 1: contatore con file di testo
Questo esempio è costituito da cinque file:

  • index.aspx
  • index.aspx.vb
  • Web.Config
  • contatore.txt
  • Utilita.vb

Vediamo ora in dettaglio i contenuti dei vari file per comprendere pienamente le tecniche utilizzate.

contatore.txt
E’ un file di testo contenente solo una riga di testo, inizialmente impostata, per semplicità, al valore “1″ (uno).
Questo file contiene l’ultimo aggiornamento del contatore degli accessi al sito ed è posto nella cartella “public“, secondo le convenzioni adottate dal provider Internet Aruba.it. Ovviamente con un provider diverso la posizione può essere diversa.

Web.Config
Questo file costituisce il file di configurazione del sito che stiamo creando.
In questo primo esempio il file Web.Config non è stato modificato e quindi non serve per la spiegazione di questa parte, ma tornerà utile per la spiegazione dell’esempio n. 3.

Utilita.vb
Questo file contiene una classe che a sua volta contiene la funzione incrementaContatore() che viene utilizzata… indovinate per cosa? Ovviamente per incrementare il contatore!
Il codice è il seguente:

  Imports System.Web.Hosting 
  Public Class Utilita 
    Public conta As Long = 0 
    Public Function incrementaContatore() 
      Dim a As String = "" 
      Dim path As String = _ 
          HostingEnvironment.ApplicationPhysicalPath() 
      My.Response.Expires = 0 
      ' leggo variabile di sessione (contatore visite) 
      conta = HttpContext.Current.Session.Item("conta") 
      ' controllo gli aggiornamenti di pagina 
      a = My.Computer.FileSystem.ReadAllText(path & _ 
          "/public/contatore.txt") 
      If conta <> a Then 
        conta = a 
        ' Incremento di 1 il valore presente nel file di testo 
        conta += 1 
        ' scrivo sul file di testo il nuovo valore 
        My.Computer.FileSystem.WriteAllText(path & _ 
            "/public/contatore.txt", conta, False) 
      End If 
      HttpContext.Current.Session.Item("conta") = conta 
      Return conta 
    End Function 
  End Class

In questo codice è possibile vedere alcune cose interessanti:

  • HostingEnvironment.ApplicationPhysicalPath():restituisce il percorso fisico dell’applicazione;
  • Imports System.Web.Hosting:importazione richiesta dall’uso di HostingEnvironment;
  • x = HttpContext.Current.Session.Item(“conta”):legge la variabile di sessione “conta“;
  • HttpContext.Current.Session.Item(“conta”) = x:imposta la variabile di sessione “conta“;
  • My.Computer.FileSystem.ReadAllText(path & “/public/contatore.txt”):legge il file contatore.txt;
  • My.Computer.FileSystem.WriteAllText(path & “/public/contatore.txt”, conta, False):scrive il file contatore.txt.

Inoltre, all’interno della funzione è stato inserito un test:

      If conta <> a Then

che serve a confrontare il valore “conta” (uguale alla variabile di sessione “conta“) e il valore “a” (uguale al contenuto del file di testo contatore.txt).
Perché viene eseguito questo test? E’ piuttosto semplice: per evitare che venga incrementato il contatore degli accessi ad ogni “refresh” della pagina da parte dell’utente (pressione del pulsante “Aggiorna” o del tasto F5). Se non si impedisse l’aggiornamento continuo, si avrebbe un contatore degli accessi troppo… generoso! In questo modo, invece, viene contato un nuovo accesso al sito se e solo se è appena stata aperta una nuova sessione. In caso contrario il contatore rimane invariato.

index.aspx
Questa è la pagina principale (l’unica) del nostro sito.
Contiene due label per la presentazione di testo fisso e una textbox per la visualizzazione del contatore degli accessi che viene aggiornata automaticamente ad ogni prima apertura di sessione.

index.aspx.vb
Infine questo è il file contenente il codice associato alla pagina index.aspx e precisamente il seguente:

  Partial Class index 
    Inherits System.Web.UI.Page 
    Protected Sub form1_Load(ByVal sender As Object, _ 
            ByVal e As System.EventArgs) _ 
            Handles form1.Load 
      Dim conta As Long 
      Dim util As New Utilita 
      conta = util.incrementaContatore() 
      Me.VisitatoreN.Text = String.Format(conta, "#####") 
    End Sub 
  End Class

Come si può vedere, tutto il codice è contenuto nella procedura che costituisce il gestore di evento Load della pagina (form1.Load).
Vengono dichiarate una variabile di tipo numerico (Long) e una variabile di tipo Utilita (istanza della classe Utilita presentata poc’anzi).
Il risultato del metodo util.incrementaContatore viene assegnato alla variabile “conta” che, opportunamente formattata, va ad aggiornare l’unica textbox della pagina che a questo punto viene automaticamente visualizzata all’utente.

Esempio 2: contatore con database Access

Anche in questo caso abbiamo cinque file, denominati come nel primo esempio.
C’è però una differenza sostanziale: al posto di un file contatore.txt contenuto nella sottocartella public, abbiamo un file database di Access denominato Contatore.mdb, posto nella cartella mdb-database.
Anche in questo caso sono state seguite le convenzioni del provider Aruba.it che prevede che i database Access siano depositati in una cartella predefinita di nome mdb-database.

Anche in questo caso analizziamo il contenuto di questo esempio, evidenziando le differenze con l’esempio precedente.

Contatore.mdb
Questo database (la versione utilizzata nell’esempio è Access 2000-2003) contiene un’unica tabella, di nome “Contatore“, con un unico campo di nome “Accessi” di tipo Numerico (Intero Lungo).
Prima di mettere “in produzione” questo esempio bisogna ricordarsi di creare (se non già fatto) un unico record in questa tabella con il valore 0 (zero).

Web.Config e index.aspx
Questi file non sono stati modificati dal primo esempio.

utilita.vb
Questo è l’unico file che è stato drasticamente modificato in questo nuovo esempio.
La funzione incrementaContatore() è stata integralmente sostituita dalla funzione incrementaContatoreDB().
Ecco il codice completo di questa classe:

  Imports System.Web.Hosting 
  Imports System.Data.OleDb 
  Public Class Utilita 
    Dim conta As Long = 0 
    Public Function incrementaContatoreDB() As Long 
      Dim path As String = _ 
          HostingEnvironment.ApplicationPhysicalPath() & _ 
          "\mdb-database\" 
      My.Response.Expires = 0 
      ' crea connessione 
      Dim cn As OleDbConnection 
      Dim ConnectionString As String = _ 
          "Provider=Microsoft.Jet.OLEDB.4.0;" & _ 
          "Data Source=" & path & "\Contatore.mdb;" & _ 
          "User ID=Admin;" & _ 
          "Password=" 
      cn = New Data.OleDb.OleDbConnection(ConnectionString) 
      cn.Open() 
      Dim SQL As String 
      ' leggo variabile di sessione (contatore visite) 
      conta = HttpContext.Current.Session.Item("conta") 
      ' controllo gli aggiornamenti di pagina 
      If conta = 0 Then 
        ' incremento del campo "Accessi" della tabella "Contatore" 
        SQL = "UPDATE Contatore SET Contatore.Accessi = [Accessi]+1;" 
        Dim comando As New OleDbCommand(SQL, cn) 
        comando.ExecuteNonQuery() 
      End If 
      ' recupero numero accessi attuale 
      SQL = "SELECT Contatore.Accessi FROM Contatore;" 
      Dim selezione As New OleDbCommand(SQL, cn) 
      conta = selezione.ExecuteScalar 
      ' scrivo variabile di sessione (contatore visite) 
      HttpContext.Current.Session.Item("conta") = conta 
      ' chiusura connessione 
      cn.Close() 
      Return conta 
    End Function 
  End Class

Alcuni commenti su questo codice:

  • anche in questo esempio si utilizza HostingEnvironment, rendendo necessaria l’import di System.Web.Hosting;
  • dato che viene effettuata una connessione ad un database Access, viene importato anche il namespace System.Data.OleDb;
  • la connessione al database viene realizzata con una stringa di connessione inserita direttamente nel codice;
  • viene utilizzata una variabile di sessione di nome “conta” come nel precedente esempio: se la variabile di sessione “conta” è uguale a zero, allora non è ancora stata impostata. Di conseguenza viene incrementato il contatore di una unità mediante un’istruzione SQL di tipo UPDATE. Tale istruzione è eseguita mediante il metodo ExecuteNonQuery di un oggetto di tipo OleDbCommand;
  • dopo l’eventuale incremento del campo Accessi della tabella Contatore del database Contatore.mdb, si recupera il valore aggiornato dello stesso campo con un’istruzione SQL di tipo SELECT;
  • a questo proposito, dato che si deve recuperare un unico valore (detto “scalare“), possiamo utilizzare un metodo ExecuteScalar, anche questa volta di un oggetto di tipo OleDbCommand;
  • infine viene aggiornata anche la variabile di sessione e chiusa la connessione.

index.aspx.vb
Questo file è stato modificato in minima parte, dato che cambia solamente la chiamata a incrementaContatoreDB, anziché a incrementaContatore.

Esempio 3: memorizzazione della stringa di connessione

Applichiamo ora le tecniche viste nel mio articolo precedente su ADO.NET 2.0 e precisamente la memorizzazione della stringa di connessione nel file di configurazione.
Trattandosi di un progetto per un sito, in questo caso non abbiamo un file app.config, bensì un file Web.Config. Cambia il nome, non di molto la sostanza.

Vediamo anche in questo caso le differenze rispetto all’esempio 2.

Contatore.mdb, index.aspx e index.aspx.vb
Questi file non sono stati modificati.

Web.Config
Questo file viene modificato con l’aggiunta della sezione come segue:

  <configuration> 
    <appSettings /> 
      <connectionStrings> 
        <clear /> 
          <add 
            name="Contatore" 
            connectionString="Provider=Microsoft.Jet.OLEDB.4.0; 
              Data Source= 
              AspNet2_GestioneContatoreAccessi/modo3/mdb-database/Contatore.mdb; 
              User ID=Admin;Password=" 
            providerName="Microsoft.Jet.OLEDB.4.0" /> 
      </connectionStrings> 
      <system.web> 
      ... (segue)

Per ragioni di leggibilità la riga “connectionString” è stata mandata a capo. Inoltre, è stata omessa parte del percorso del database. Per seguire l’esempio è opportuno che essa venga completata, ovviamente.

Utilita.vb
Questa classe è stata modificata con l’aggiunta della funzione GetConnectionString che serve a recuperare la stringa di connessione dalla sezione del file Web.Config.
Il codice aggiunto è un adattamento di un codice di esempio preso dalla documentazione di Visual Studio 2005, alla quale si rimanda per i dettagli implementativi:

Shared Function GetConnectionString(ByVal ConnectionStringName _ 
        As String) As String 
    ' Get the default connectionStrings section, 
    Dim connectionStringsSection As ConnectionStringsSection = _ 
        Web.Configuration.WebConfigurationManager.GetWebApplicationSection( _ 
            "connectionStrings") 
    ' Get the connectionStrings key,value pairs collection. 
    Dim connectionStrings As ConnectionStringSettingsCollection = _ 
        connectionStringsSection.ConnectionStrings 
    ' Get the collection enumerator. 
    Dim connectionStringsEnum As IEnumerator = _ 
        connectionStrings.GetEnumerator() 
    ' Loop through the collection and 
    ' display the connectionStrings key, value pairs. 
    Dim i As Integer = 0 
    Dim cs As String = "" 
    While connectionStringsEnum.MoveNext() 
        Dim nome As String = connectionStrings(i).Name 
        If nome = ConnectionStringName Then 
            cs = connectionStrings(i).ConnectionString 
            Exit While 
        End If 
        i += 1 
    End While 
    Return cs 
End Function

Una importante considerazione su questo codice: la funzione prende come parametro il nome assegnato alla stringa di connessione, corrispondente alla proprietà “name” indicata nel file Web.Config.
Inoltre all’interno del ciclo While viene effettuato un test sulla corrispondenza tra il nome cercato e il nome trovato in Web.Config e solo se corrisponde viene presa la stringa di connessione corrispondente e restituita al chiamante.
Cosa significa questo? E’ molto semplice: è possibile memorizzare più stringhe di connessione nel file Web.Config assegnando loro nomi diversi ed è possibile estrarre la stringa di connessione che ci serve in un dato momento con un codice molto pulito ed elegante.

Conclusioni
Come abbiamo visto, non è difficile implementare un contatore degli accessi nel nostro sito Internet.
Abbiamo visto anche come in Visual Studio 2005 molti dei concetti che abbiamo imparato per un’applicazione tradizionale valgano anche per un’applicazione web: dopo tutto ADO.NET 2.0 è implementato in uno strato applicativo comune ai due modelli di programmazione.
Il codice relativo a questi esempi e scaricabile qui.

About these ads

Pubblicato il 20 gennaio 2008, in ADO.NET, ASP.NET con tag , , . Aggiungi il permalink ai segnalibri. Lascia un commento.

Rispondi

Inserisci i tuoi dati qui sotto o clicca su un'icona per effettuare l'accesso:

Logo WordPress.com

Stai commentando usando il tuo account WordPress.com. Chiudi sessione / Modifica )

Foto Twitter

Stai commentando usando il tuo account Twitter. Chiudi sessione / Modifica )

Foto di Facebook

Stai commentando usando il tuo account Facebook. Chiudi sessione / Modifica )

Google+ photo

Stai commentando usando il tuo account Google+. Chiudi sessione / Modifica )

Connessione a %s...

Iscriviti

Ricevi al tuo indirizzo email tutti i nuovi post del sito.

Unisciti agli altri 846 follower

%d blogger cliccano Mi Piace per questo: