ASP.NET 2.0 usa un identificatore univoco per ogni utente che possiede un profilo. A volte però conviene associare un profilo ad un utente anonimo, un utente che non ha effettuato il Login, che non si è mai autenticato e che quindi risulta sconosciuto all'applicazione.
Possiamo immaginare un esempio per quest'ultimo caso considerando un'applicazione di e-commerce. Lo scopo dell'applicazione (sito) di e-commerce è vendere i propri prodotti agli internauti. I prodotti vengono esposti nelle pagine del sito e descritti, prima brevemente, e poi in dettaglio.
In genere conviene esporre i prodotti in pagine accessibili a tutti, evitando di proporre subito il Login per l'autenticazione o l'iscrizione. In questo modo l'utente internet senza troppe difficoltà può visualizzare i prodotti in vendita e decidere se questi incontrano le sue esigenze.
Una ulteriore possibilità consiste nell'associare all'utente, ancora anonimo, un carrello della spesa, in modo che questi lo possa riempire con i prodotti che sceglie.
Terminata la fase di shopping, libera ed accessibile a tutti, per il ritiro degli articoli scelti, l'applicazione richiede all'utente alcune informazioni, come ad esempio il numero di carta di credito o altro mezzo per il pagamento, oltre che nome, cognome e indirizzo al quale consegnare gli articoli comprati.
La fase di "ritiro della merce" quindi, dal punto di vista dello sviluppatore, prevede un trasferimento di informazioni da un utente non autenticato ad un utente autenticato. Vedremo come realizzare questa trasformazione in un altro articolo, per ora concentriamoci sulla prima parte di sviluppo di una applicazione di e-commerce. La parte che prevede la possibilità di un utente anonimo di accedere al sito, scegliere i prodotti in vendita e riempire un carrello della spesa.
Per fare questo, ASP.NET 2.0 ci viene incontro, dandoci la possibilità di utilizzare l'oggetto Profile
anche con un utente anonimo. In questo caso l'individuazione univoca dell'utente avviene mediante l'uso del GUID
, sigla che sta per: Globally Unique Identifier.
Realizziamo quindi un carrello della spesa di un sito di e-commerce, utilizzando l'oggetto Profile
per utenti non ancora autenticati.
Partiamo dall'esempio realizzato in un precedente articolo che possiamo scaricare da qui rinominandolo "ProfiloNonAutenticato".
Aggiungiamo al sito la cartella "Immagini" ed al suo interno poniamo almeno due immagini di due prodotti in vendita. Possiamo, ad esempio, prendere le immagini visualizzate in figura, dal sito www.fase2sport.com.
Aggiungiamo ora una nuova pagina, di nome "Prodotti.aspx", nella cartella principale dell'applicazione.
In "Prodotti.aspx" è presente una tabella con le figure dei prodotti ed alcune le Label
: "Label1Id", "Label2Des", "Label3Prezzo", "Label4Id", "Label5Des" e "Label6Prezzo". Ci sono inoltre 2 Button
: "Button1Aggiungi" e "Button2Aggiungi".
Chiaramente in un caso reale queste informazioni andrebbero estratte da un database e la tabella sarebbe dinamica, mentre nel nostro esempio i valori messi e la tabella sono statici, e ci servono solo come punto di partenza per arrivare velocemente alla realizzazione del carrello della spesa.
Procediamo ora pensando di aggiungere gli articoli, che l'utente sceglie, al suo oggetto Profile
.
Il carrello della spesa lo possiamo immaginare come un oggetto che è formato da un Array di elementi. Ogni elemento dell'Array rappresenta un articolo scelto dall'utente.
Aggiungiamo quindi una classe alla nostra applicazione e chiamiamola "Articolo.cs". Questa classe deve rappresentare un articolo in vendita sul sito, quindi le informazioni minime che deve contenere sono l'identificatore dell'articolo, in modo da poterlo identificare univocamente, e la quantità che l'utente ha deciso di acquistare.
Listato 1. Implementare "Articolo.cs"
public class Articolo
{
public String identificatore;
public int quantità;
// costruttore di default necessario per la serializzazione
public Articolo() { }
// costruttore da utilizzare
public Articolo(String identificatore, int quantità)
{
this.identificatore = identificatore;
this.quantità = quantità;
}
}
La classe Articolo
è costituita da due variabili di istanza pubbliche, String identificatore
e int quantità
, da un costruttore che ha il compito di impostare queste variabili e da un costruttore di default che va obbligatoriamente inserito se vogliamo serializzare i dati in formato XML o in formato binario. La serializzazione inoltre implica che le variabili di istanza siano dichiarate pubbliche, come abbiamo fatto.
Aggiungiamo ora un'altra classe che chiamiamo "Carrello.cs".
Il carrello deve essere costituito da un Array che contine degli articoli, cioè elementi di tipo Articolo
. Per fare questo utilizziamo un ArrayList
di oggetti di tipo Articolo
:
Listato 2. Implementare "Carrello.cs"
...
using System.Collections;
using System.Xml.Serialization;
...
[XmlInclude(typeof(Articolo))]
public class Carrello
{
public ArrayList articoli;
public Carrello()
{
articoli = new ArrayList();
}
public void aggiungiArticolo(string identificatore, int quantità)
{
articoli.Add(new Articolo(identificatore, quantità));
}
}
La classe Carrello
, costruita in questo modo, è molto semplice da utilizzare. Per aggiungere un nuovo articolo, basta chiamare il metodo aggiungiArticolo
a cui bisogna passare l'identificatore e la quantità.
Il costruttore della classe si occupa di istanziare un oggetto di tipo ArrayList
su cui anche dall'esterno si potranno utilizzare i metodi e le proprietà della classe ArrayList
.
Con l'attributo [XmlInclude(typeof(Articolo))]
diciamo di serializzare gli oggetti della classe Carrello
in elementi di tipo Articolo
.
Abbiamo inoltre bisogno dei mamespace
: System.Collections
e System.Xml.Serialization
.
Adesso che abbiamo le nostre due classi, passiamo al file di configurazione.< Per abilitare l'identificazione degli utenti anonimi bisogna infatti aggiungere alla sezione <system.web>
del Web.config il tag:
<anonymousidentification enabled="true" />
Per poi memorizzare il carrello nell'oggetto Profile
dell'utente bisogna aggiungerlo alle sue proprietà:
Listato 3. Web.config
<?xml version="1.0"?>
<configuration>
<appSettings/>
<connectionStrings/>
<system.web>
<compilation debug="true"/>
<authentication mode="Forms"/>
<anonymousIdentification enabled="true"/>
<profile>
<properties>
<add name="Nome"/>
<add name="Cognome"/>
<add name="UltimoCollegamento" type="System.DateTime"/>
<add name="Carrello" allowAnonymous="true" type="Carrello" serializeAs="Xml"/>
<group name="Indirizzo">
<add name="Via"/>
<add name="Numero"/>
<add name="Nazione"/>
<add name="CAP"/>
</group>
</properties>
</profile>
</system.web>
</configuration>
Nella proprietà Carrello
del tag <Profile>
, abbiamo abilitato gli utenti anonimi, abbiamo specificato il tipo di dati, che sono oggetti di tipo Carrello
, ed il tipo di serializzazione.
In questo modo, appena un utente anonimo entra nel sito, l'applicazione gli associa un oggetto di tipo Carrello
che sarà accessibile allo sviluppatore mediante l'oggetto Profile
.
Passiamo ora alla "Prodotti.aspx.cs" ed aggiungiamo un gestore unico per l'evento OnClick
su uno dei due pulsanti.
Listato 4. ButtonAggiungi_Click
protected void ButtonAggiungi_Click(object sender, EventArgs e)
{
Carrello carrelloUtente = Profile.Carrello;
switch (((Button)sender).ID)
{
case "Button1Aggiungi":
carrelloUtente.aggiungiArticolo(Label1Id.Text, 1);
break;
case "Button2Aggiungi":
carrelloUtente.aggiungiArticolo(Label4Id.Text, 1);
break;
}
Profile.Carrello = carrelloUtente;
}
Definiamo carrelloUtente
di tipo Carrello
ed assegniamogli l'oggetto già esistente Profile.Carrello
.
Non serve istanziare un nuovo oggetto di tipo Carrello
, in quanto, come abbiamo impostato nel file di configurazione, tale oggetto viene creato per tutti gli utenti, anonimi e autenticati.
Possiamo inoltre mostrare un messaggio all'utente ricordandogli che non si è ancora autenticato.
Listato 5. Messaggio per l'utente non autenticato
protected void Page_Load(object sender, EventArgs e)
{
MembershipUser utente = Membership.GetUser();
if (utente == null)
Response.Write("Non hai ancora effettuato il Login!");
}
A questo punto testiamo la nostra nuova pagina facendo partire "Prodotti.aspx"
Clicchiamo su entrambi i pulsanti "Aggiungi al carrello" ed usciamo dall'applicazione e visualizziamo i dati della tabella aspnet_Profile
del file di database "ASPNETDB.MDF".
Poiché abbiamo impostato sul file di configurazione l'attributo serializeAs="Xml"
, l'applicazione ha riempito il campo PropertyValuesString
con una serializzazione di tipo XML.
Se infatti copiamo sul blocco note il contenuto del campo PropertyValuesString
del nostro Carrello
, otteniamo:
in cui si riconoscono gli articoli che abbiamo scelto.
Se invece vogliamo operare una serializzazione binaria, dobbiamo aggiungere l'attributo [Serializable()]
alle nostre classi ed impostare sul Web.config l'attributo serializeAs="Binary"
nella definizione della proprietà Carrello
.
Se ora esaminiamo il contenuto della tabella aspnet_Users
del file di database "ASPNETDB.MDF", notiamo la presenza dell'utente anonimo, a cui è stato associato uno UserId
.
Se vogliamo leggere lo UserName
(non lo UserId
) dell'utente anonimo che sta visitando il nostro sito possiamo ricorrere alla proprietà AnonymousID
dell'oggetto Request
: Request.AnonymousID
L'esempio realizzato in questo articolo, privato del database, può essere scaricato da qui.