Nessun risultato. Prova con un altro termine.
Guide
Notizie
Software
Tutorial

Convertire utenti anonimi in utenti dell'applicazione

Usare l'oggetto Profile per modificare lo stato di autenticazione di un utente
Usare l'oggetto Profile per modificare lo stato di autenticazione di un utente
Link copiato negli appunti

In un articolo precedente abbiamo realizzato un carrello della spesa, utilizzando l'oggetto Profile per utenti non ancora autenticati.

Il passo successivo nell'implementazione di un'applicazione di e-commerce è quello di trasferire le informazioni associate all'utente non autenticato, che visitando il sito ha riempito il suo carrello della spesa, ad un utente autenticato, in quanto l'utente anonimo, per ritirare la merce dovrà autenticarsi. Vediamo come fare lavorando su un esempio.

Prendiamo l'applicazione che abbiamo sviluppato nell'articolo precedente, e rinominiamola "TrasferireProfilo".

Aggiungiamo il file "Global.asax".

Per chi non lo sapesse, il file "Global.asax" è un file facoltativo che può essere inserito in un'applicazione ASP.NET per gestire eventi a livello di applicazione o di sessione. Il "Global.asax" va messo nella cartella principale dell'applicazione e non può essere editato o visualizzato con il browser mediante una richiesta URL.

Ci serve il "Global.asax" per poter gestire l'evento ProfileModule.MigrateAnonymous che viene generato da un'applicazione ASP.NET 2.0 quando un utente anonimo, che possiede un profilo, effettua l'accesso, cioè si autentifica.

Sarà sempre sul Global.asax che implementeremo il gestore di quest'evento. Quindi, con il VWD, aggiungiamo alla nostra applicazione l'Elemento denominato "Classe di Applicazione Globale".

Troveremo già impostati i metodi: Application_Start, Application_End, Application_Error, Session_Start e Session_End; questi metodi servono a gestire i relativi eventi a livello di applicazione e sessione. Lasciamo stare i metodi già impostati ed aggiungiamo quello che ci interessa.

Listato 1. Profile_OnMigrateAnonymous sul Global.asax

void Profile_OnMigrateAnonymous(object sender, ProfileMigrateEventArgs args)
{
  // otteniamo il profilo dell'utente anonimo
  ProfileCommon anonymousProfile = Profile.GetProfile(args.AnonymousID);
  // trasferiamo il carrello
  Profile.Carrello = anonymousProfile.Carrello;
  // cancelliamo il profilo anonimo
  ProfileManager.DeleteProfile(args.AnonymousID);
  // cancelliamo l'utente anonimo dal database
  Membership.DeleteUser(args.AnonymousID);
  // cancelliamo il cookie dell'utente anonimo
  AnonymousIdentificationModule.ClearAnonymousIdentifier();
}

Come possiamo notare dal listato, la prima cosa che facciamo, è l'estrazione del profilo dell'utente anonimo mediante l'uso della proprietà AnonymousID. Poi trasferiamo il carrello della spesa, cancelliamo il profilo anonimo e l'utente anonimo, che non ci servono più, ed eliminiamo il cookie associato.

Il Profile_OnMigrateAnonymous sul Global.asax si metterà in funzione quando l'utente esegue il Login, quindi per il trasferimento del profilo abbiamo fatto tutto.

Realizziamo ora una pagina che ci consenta di visualizzare il contenuto del carrello della spesa in modo che l'utente possa controllare quello che sta acquistando.

Nella classe Articolo abbiamo messo le variabili di istanza identificatore e quantità che sono le informazioni minime ma sufficienti, a descrivere completamente l'articolo. Infatti per avere la descrizione completa, basterebbe accedere al database con l'identificatore che è univoco per ogni articolo. Nel nostro esempio però, non disponendo di un database, avendo semplificato questo aspetto, abbiamo posizionato due articoli sulla pagina Prodotti.aspx con le informazioni: identificatore, descrizione e prezzo.

Ora, per visualizzare il carrello, ci conviene portarci dietro anche informazioni come descrizione e prezzo. Ciò per avere una visione completa degli articoli scelti.

Operiamo quindi una piccola modifica alla classe Articolo inserendo fra le variabili di istanza anche descrizione e prezzo.

Listato 2. Aggiunta di informazioni alla classe Articolo

public class Articolo
{
  public String identificatore;
  public String descrizione;
  public String prezzo;
  public int quantità;
  // costruttore di default necessario per la serializzazione
  public Articolo() { }
  // costruttore da utilizzare
  public Articolo(String identificatore, String descrizione, String prezzo, int quantità)
  {
    this.identificatore = identificatore;
    this.descrizione = descrizione;
    this.prezzo = prezzo;
    this.quantità = quantità;
  }
}

Aggiorniamo quindi tutti i punti dell'applicazione in cui viene chiamato il costruttore della classe Articolo.

Il costruttore modificato viene chiamato solo nella classe Carrello. Operiamo la modifica:

Listato 3. Modifica alla classe Carrello

[XmlInclude(typeof(Articolo))]
public class Carrello
{
  public ArrayList articoli;
  public Carrello()
  {
    articoli = new ArrayList();
  }
  public void aggiungiArticolo(String identificatore, String descrizione, String prezzo, int quantità)
  {
    articoli.Add(new Articolo(identificatore, descrizione, prezzo, quantità));
  }
}

Modifichiamo ora tutti i punti dell'applicazione in cui viene chiamato il metodo aggiungiArticolo poiché ne abbiamo modificato la firma. Tale metodo viene chiamato in ButtonAggiungi_Click della Prodotti.aspx.cs. Operiamo la modifica:

Listato 4. Modifica a ButtonAggiungi_Click in Prodotti.aspx.cs

protected void ButtonAggiungi_Click(object sender, EventArgs e)
{
  Carrello carrelloUtente = Profile.Carrello;
  switch (((Button)sender).ID)
  {
    case "Button1Aggiungi":
      carrelloUtente.aggiungiArticolo(Label1Id.Text, Label2Des.Text, Label3Prezzo.Text, 1);
    break;
    case "Button2Aggiungi":
      carrelloUtente.aggiungiArticolo(Label4Id.Text, Label5Des.Text, Label6Prezzo.Text, 1);
    break;
  }
  Profile.Carrello = carrelloUtente;
}

Realizziamo ora la pagina per visualizzare il carrello della spesa.

Possiamo inserire la pagina all'interno della cartella Autenticati in modo che l'utente, per vederla, debba effettuare il Login, e quindi avvenga il trasferimento del profilo dall'utente anonimo all'utente autenticato.

Chiamiamo la pagina Acquisti.aspx.

In Acquisti.aspx mettiamo la Label Label1Msg mentre nella Acquisti.aspx.cs, mettiamo una chiamata al metodo visualizzaSpesa nel Page_Load.

Implementiamo ora il metodo visualizzaSpesa.

Qui dobbiamo visualizzare tutti gli articoli presenti nel carrello dell'utente che si è appena autenticato. Il trasferimento del carrello, in seguito all'autenticazione, viene gestito nel Global.asax che abbiamo già sistemato.

La prima cosa che dobbiamo fare è definire un riferimento all'oggetto Carrello incluso nel profilo dell'utente. Poiché la classe Carrello ha al suo interno un ArrayList che contiene oggetti di tipo Articolo, possiamo utilizzare la proprietà Count dell'ArrayList per verificare se il carrello è vuoto oppure no. Se il carrello contiene uno o più articoli, li estraiamo con l'istruzione foreach applicata all'ArrayList.

Listato 5. Il metodo visualizzaSpesa() in Acquisti.aspx.cs

protected void visualizzaSpesa()
{
  Carrello carrello = Profile.Carrello;
  if (carrello.articoli.Count != 0)
  {
    Label1Msg.Text = "Il tuo carrello contiene: " + "<br />";
    Label1Msg.Text += "====================" + "<br />";
    foreach (Articolo articolo in carrello.articoli)
    {
      Label1Msg.Text += "Articolo numero...: " + articolo.identificatore + "<br />";
      Label1Msg.Text += "Descrizione.......: " + articolo.descrizione + "<br />";
      Label1Msg.Text += "Prezzo............: " + articolo.prezzo + "<br />";
      Label1Msg.Text += "Quantità..........: " + articolo.quantità.ToString() + "<br />";
      Label1Msg.Text += "====================" + "<br />";
    }
  }
  else
    Label1Msg.Text = "Non hai effettuato acquisti." + "<br />";
}

Per semplificarci la vita in fase di test, in Prodotti.aspx mettiamo un link ad Acquisti.aspx ed in Acquisti.aspx mettiamo un link a Prodotti.aspx in modo che si possa navigare tra le due pagine.

Se nella nostra applicazione non è presente alcun utente, inseriamone almeno uno con il WAT.

Ora, per fare un test, editiamo le tabelle aspnet_Profile ed aspnet_Users in modo da poter monitorare gli utenti presenti ed i profili.

Supponiamo di aver inserito mediante il WAT l'utente Pippo.

Su aspnet_Users avremo:

Figura 1. Situazione iniziale su aspnet_Users
Situazione iniziale su aspnet_Users

Se visualizziamo aspnet_Profile notiamo che è vuota, come è lecito aspettarsi, in quanto nessun utente si è ancora collegato e quindi nessun profilo è stato creato.

Ora editiamo la pagina Prodotti.aspx e premiamo F5.

Scegliamo i due prodotti cliccando sul relativo pulsante "Aggiungi al carrello".

Se, in questo momento, senza chiudere il browser verifichiamo il contenuto delle due tabelle: notiamo la presenza dell'utente anonimo sulla aspnet_Users e del suo profilo con il carrello sulla aspnet_Profile.

Figura 2. Utente anonimo presente su aspnet_Users
aspnet_Users
Figura 3. Profilo dell'utente anonimo con il carrello presente su aspnet_Profile
Profilo dell'utente anonimo con il carrello presente su aspnet_Profile

Per verificare che il carrello appartiene all'utente anonimo possiamo controllare lo UserId che deve coincidere per lo stesso utente nelle due tabelle.

Siamo rimasti per un po' con il browser aperto dopo aver effettuato la scelta dei prodotti:

Figura 4. Dopo la scelta dei prodotti
Dopo la scelta dei prodotti

Adesso clicchiamo su "Visualizza acquisti" che ci conduce alla pagina per visualizzare il carrello e ci obbliga ad effettuare il Login.

Effettuiamo il Login con l'utente Pippo.

Ci viene visualizzato il carrello della spesa, che coincide con i prodotti che abbiamo scelto quando eravamo ancora anonimi:

Figura 5. Il carrello della spesa dell'utente autenticato
Il carrello della spesa dell'utente autenticato

Se ora andiamo a vedere che cosa è successo sulle due tabelle notiamo che su aspnet_Users non c'è più l'utente anonimo, in quanto lo cancelliamo con il Global.asax quando non ci serve più, e su aspnet_Profile il carrello è passato all'utente autenticato come possiamo verificare confrontando gli UserId. Il profilo dell'utente anonimo è stato inoltre eliminato.

L'esempio sviluppato in questo articolo, privato del database per motivi di spazio, può essere scaricato da qui.

Ti consigliamo anche