In questo articolo esamineremo il modo di modificare i dati degli utenti di un'applicazione web utilizzando le classi Membership
e MembershipUser
.
La classe Membership
è la classe con cui sono costruiti i nuovi controlli Login di ASP.NET 2.0.
L'approccio più versatile e flessibile di trattare i dati degli utenti consiste nella stesura di codice "ad hoc" per l' applicazione da implementare e, quindi, l'esigenza di una conoscenza più approfondita delle classi menzionate sopra è un must, cioè è un dovere.
Per realizzare un esempio di funzionamento degli strumenti che le classi Memebership
e MembershipUser
ci mettono a disposizione, partiamo dall'esempio sviluppato nell'articolo "Assegnare ruoli agli utenti" che possiamo scaricare da qui e rinominare "GestioneUtenti".
Nella cartella "Inscritti" aggiungiamo un nuovo Web Form di nome "InformazioniUtente.aspx".
Va messo nella cartella "Inscritti" perché deve essere accessibile a tutti gli utenti che hanno effettuato il Login, compreso l'amministratore.
In "InformazioniUtente.aspx" costruiamo la tabella mostrata in figura.
Nella tabella ci sono delle caselle di testo: "TextBoxUserId", "TextBoxPassword", "TextBoxNewPassword", "TextBoxDomanda", "TextBoxRisposta" e "TextBoxEmail". Tra queste la "TextBoxUserId" deve essere di sola lettura.
Ci sono poi i pulsanti: "ButtonCambiaPassword", "ButtonCambiaDomanda" e "ButtonCambiaEmail".
Al di sotto abbiamo un'etichetta per visualizzare ulteriori informazioni ed un altra in rosso che useremo per visualizzare eventuali messaggi di errore.
La prima cosa da fare è estrarre le informazioni dell'utente loggato. Per farlo modifichiamo il codice interno della pagina, nel file "InformazioniUtente.aspx.cs", dove implementiamo il Page_Load
nel seguente modo:
Listato 1. Page_Load in InformazioniUtente.aspx.cs
protected void Page_Load(object sender, EventArgs e)
{
MembershipUser user = Membership.GetUser();
LabelAltreInfo.Text = "";
LabelAltreInfo.Text += "Ultimo Login effettuato il " + user.LastLoginDate + "<br />";
LabelAltreInfo.Text += "Account utente creato il " + user.CreationDate + "<br />";
LabelAltreInfo.Text += "Cambiamento Password effettuato il " + user.LastPasswordChangedDate + "<br />";
if (!Page.IsPostBack)
{
TextBoxUserId.Text = user.UserName.ToString();
TextBoxDomanda.Text = user.PasswordQuestion;
TextBoxEmail.Text = user.Email;
}
}
Nel Page_Load
definiamo un oggetto della classe MembershipUser
. Non occorre istanziare un nuovo oggetto perché ne usiamo uno già istanziato, ovvero quello contenente i dati dell'utente che ha effettuato il Login. Per farlo è sufficiente una chiamata al metodo statico Membership.GetUser()
che restituisce un puntatore all'oggetto corrente.
Se l'utente non è autenticato, GetUser()
restituisce un riferimento a null
.
Valorizziamo "LabelAltreInfo" inserendovi le informazioni sulla ultima data di Login, la data di creazione dell'utente e la data dell'ultimo cambiamento della Password e le tre TextBox
con le relative informazioni, utilizzando le relative proprietà della classe MembershipUser
(LastLoginDate
, CreationDate
, LastPasswordChangedDate
, UserName
, PasswordQuestion
ed Email
).
Nota: La classe MembershipUser
non ci consente di leggere la risposta alla domanda di sicurezza.
Implementiamo ora il gestore dell'evento OnClick
sul pulsante "ButtonCambiaPassword".
Listato 2. ButtonCambiaPassword_Click
protected void ButtonCambiaPassword_Click(object sender, EventArgs e)
{
MembershipUser user = Membership.GetUser();
// cambiamento password
if (TextBoxPassword.Text != "" &&
(TextBoxPassword.Text != TextBoxNewPassword.Text) &&
TextBoxNewPassword.Text != "")
// l'utente sta tentando di cambiare la password
try
{
if (user.ChangePassword(TextBoxPassword.Text, TextBoxNewPassword.Text))
LabelMsg.Text = "Password modificata";
else
LabelMsg.Text = "Tentativo di modifica Password fallito";
}
catch (Exception ex)
{
LabelMsg.Text = ex.Message;
}
else
LabelMsg.Text = "Campo richiesto vuoto o nuova Password uguale a quella vecchia";
}
Al solito definiamo un riferimento all'oggetto di tipo MembershipUser
che contiene i dati dell'utente loggato. Lo dobbiamo fare un'altra volta perché quello fatto nel Page_Load
rimane valido (visibile) solo all'interno del Page_Load
stesso.
Tentiamo poi di aggiornare la Password e se qualcosa va storto catturiamo l'eccezione lanciata e visualizziamone il relativo messaggio.
Il metodo ChangePassword
vuole la vecchia e la nuova password e restituisce un valore booleano che è true
se l'aggiornamento ha avuto successo.
Implementiamo ora il metodo ButtonCambiaDomanda_Click
che gestisce il click sul pulsante "ButtonCambiaDomanda".
Listato 3. ButtonCambiaDomanda_Click
protected void ButtonCambiaDomanda_Click(object sender, EventArgs e)
{
MembershipUser user = Membership.GetUser();
if (TextBoxPassword.Text != "" && TextBoxDomanda.Text != "" && TextBoxRisposta.Text != "")
try
{
if (user.ChangePasswordQuestionAndAnswer(TextBoxPassword.Text, TextBoxDomanda.Text, TextBoxRisposta.Text))
LabelMsg.Text = "Domanda e risposta di sicurezza modificate";
else
LabelMsg.Text = "Tentativo di modifica domanda e risposta di sicurezza fallito";
}
catch (Exception ex)
{
LabelMsg.Text = ex.Message;
}
else
LabelMsg.Text = "Campo richiesto vuoto";
}
L'implementazione di ButtonCambiaDomanda_Click
è simile a quanto già fatto per ButtonCambiaPassword_Click
. Questa volta il metodo utilizzato è il ChangePasswordQuestionAndAnswer
che prende in input la Password, la domanda di sicurezza e la relativa risposta, restituendo un valore booleano con l'esito dell'aggiornamento.
Infine implementiamo il metodo per cambiare l'e-mail:
Listato 4. ButtonCambiaEmail_Click
protected void ButtonCambiaEmail_Click(object sender, EventArgs e)
{
MembershipUser user = Membership.GetUser();
user.Email = TextBoxEmail.Text;
try
{
Membership.UpdateUser(user);
LabelMsg.Text = "e-mail modificata";
}
catch (Exception ex)
{
LabelMsg.Text = ex.Message;
}
}
Questo metodo aggiorna la proprietà Email
dell'oggetto "user" e poi utilizza il metodo UpdateUser
, che prende come parametro l'oggetto "user" stesso, per aggiornare fisicamente i dati sul database.
A questo punto possiamo fare un test per verificare il funzionamento della nostra pagina.
Effettuiamo il Login con un utente registrato ed otteniamo:
Proviamo a cambiare la Password. Otteniamo un eccezione se la nuova Password non rispetta le regole:
Testiamo gli altri messaggi di errore e l'aggiornamento della Password. Una volta convinti che tutto funziona per bene, realizziamo una pagina che consenta all'amministratore di visualizzare tutti gli utenti registrati nel sito.
Aggiungiamo quindi un nuovo Web Form di nome "utentiRegistrati.aspx" alla cartella "Amministratore" ed aggiungiamo un GridView
.
Passiamo poi alla visualizzazione del coidce ("utentiRegistrati.aspx.cs") ed implementiamo il Page_Load
:
Listato 5. Page_Load in utentiRegistrati.aspx.cs
protected void Page_Load(object sender, EventArgs e)
{
MembershipUserCollection users = Membership.GetAllUsers();
GridView1.DataSource = users;
GridView1.DataBind();
}
Questo codice ha il compito di popolare il GridView
con i dati di tutti gli utenti del sito. Definisce quindi una Collection
contenente gli utenti, mediante il metodo GetAllUsers()
ed assegna poi la collezione estratta al DataSource
del GridView
. Non ci resta che fare un test per verificare che funzioni.
Prima di testare realizziamo una pagina alla quale utenti possono accedere per resettare la propria Password nel caso l'abbiano dimenticata. La pagina deve essere accessibile agli utenti che non riescono a fare il Login quindi va inserita nella cartella principale del sito, o meglio, non va messa in una cartella protetta. Chiamiamo questa nuova pagina "resetPassword.aspx".
Qui dobbiamo inserire il Nome Utente, dare Invio per ricevere la Domanda di sicurezza. Inserire la risposta e dare Invio, e, se la risposta è giusta, otteniamo la nuova Password e possiamo ritentare il Login. Se la risposta è sbagliata otteniamo un messaggio nell'etichetta in rosso.
Nella pagina di Login possiamo inserire un collegamento a questa nuova pagina, in modo che gli utenti che non ricordano la Password, possano facilmente raggiungerla. Nella resetPassword.aspx
abbiamo messo un link alla pagina di Login in modo che l'utente possa provare di nuovo ad accedere con la nuova Password.
Implementiamo ora la resetPassword.aspx.cs
scrivendo il codice per i gestori degli eventi OnClick
sui due pulsanti:
Listato 6. Implementazione dei gestori OnClick su resetPassword.aspx.cs
protected void ButtonInvioNome_Click(object sender, EventArgs e)
{
MembershipUser user = Membership.GetUser(TextBoxNome.Text, false);
LabelDomanda.Text = user.PasswordQuestion;
}
protected void ButtonInvioRisposta_Click(object sender, EventArgs e)
{
MembershipUser user = Membership.GetUser(TextBoxNome.Text, false);
try
{
LabelNewPassword.Text = user.ResetPassword(TextBoxRisposta.Text);
}
catch (Exception ex)
{
LabelMsg.Text = ex.Message;
}
}
Il primo gestore usa il metodo GetUser
a cui passa il nome dell'utente ed il valore booleano false
che indica che l'utente non è on line. Riempie poi "LabelDomanda" per mezzo della proprietà PasswordQuestion
della classe MembershipUser
.
Il secondo gestore ricava l'utente come il primo e tenta il reset della Password con il metodo ResetPassword
a cui passa la risposta di sicurezza. Se qualcosa va storto lancia un'eccezione e manda un messaggio.
Facciamo un test immaginando che l'utente "Pippo" fallisca il Login
perché non ricorda la Password.
Dalla pagina di Login clicca poi sul link "Password dimenticata?", che avevamo inserito, e arriva alla pagina "Reset Password". Qui inserisce il suo nome e da Invio. Riceve la domanda di sicurezza. Inserisce la risposta e da Invio. Se la risposta è giusta ottiene la Password.
Il passo successivo è di effettuare il Login con la Password ottenuta.
Verifichiamo poi che mettendo una risposta sbagliata ci ritorni un messaggio d'errore.
L'esempio sviluppato in questo articolo, privato del database per comodità, può essere scaricato da qui.