Condividi tramite


Creazione di account utente (VB)

di Scott Mitchell

Nota

Poiché questo articolo è stato scritto, i provider di Membership ASP.NET sono stati sostituiti da ASP.NET Identity. È consigliabile aggiornare le app per usare ASP.NET Identity Platform anziché i provider di appartenenze presenti al momento della scrittura di questo articolo. ASP.NET Identity offre numerosi vantaggi rispetto al sistema di appartenenza ASP.NET, tra cui :

  • Prestazioni migliori
  • Estendibilità e testbilità migliorate
  • Supporto per OAuth, OpenID Connect e autenticazione a due fattori
  • Supporto delle identità basate sulle attestazioni
  • Migliore interoperabilità con ASP.Net Core

Scaricare il codice o scaricare il PDF

In questa esercitazione si esaminerà l'uso del framework di appartenenza (tramite SqlMembershipProvider) per creare nuovi account utente. Verrà illustrato come creare nuovi utenti programmaticamente e tramite il controllo CreateUserWizard predefinito di ASP.NET.

Introduzione

Nell'esercitazione precedente abbiamo installato lo schema dei servizi applicativi in un database, che ha aggiunto le tabelle, le viste e le stored procedure necessarie per SqlMembershipProvider e SqlRoleProvider. Questa operazione ha creato l'infrastruttura necessaria per il resto delle esercitazioni di questa serie. In questa esercitazione si esaminerà l'uso del framework di appartenenza (tramite SqlMembershipProvider) per creare nuovi account utente. Verrà illustrato come creare nuovi utenti programmaticamente e tramite il controllo CreateUserWizard predefinito di ASP.NET.

Oltre a imparare a creare nuovi account utente, sarà anche necessario aggiornare il sito Web demo che abbiamo creato per la prima volta nell'esercitazione An Overview of Forms Authentication. L'applicazione web demo ha una pagina di login che convalida le credenziali degli utenti con le coppie di nome utente e password hard-coded. Inoltre, Global.asax include il codice che crea oggetti personalizzati IPrincipal e IIdentity per gli utenti autenticati. La pagina di accesso verrà aggiornata per convalidare le credenziali degli utenti rispetto al Membership framework e rimuovere la logica di principal e identità personalizzati.

È ora di iniziare.

Lista di controllo per l'autenticazione basata su moduli e l'iscrizione

Prima di iniziare a usare il framework di appartenenza, è necessario esaminare i passaggi importanti eseguiti per raggiungere questo punto. Quando si usa il framework di appartenenza con SqlMembershipProvider in uno scenario di autenticazione basata su form, è necessario eseguire i passaggi seguenti prima di implementare la funzionalità Di appartenenza nell'applicazione Web:

  1. Abilitare l'autenticazione basata su modulo. Come illustrato in Panoramica dell'autenticazione basata su form, l'autenticazione basata su form è abilitata modificando e impostando Web.config l'attributo <authentication> dell'elemento mode su .Forms Con l'autenticazione basata su form abilitata, ogni richiesta in ingresso viene esaminata per un ticket di autenticazione basata su form, che, se presente, identifica il richiedente.
  2. Aggiungere lo schema dei servizi dell'applicazione al database appropriato. Quando si usa SqlMembershipProvider, è necessario installare lo schema dei servizi dell'applicazione in un database. In genere questo schema viene aggiunto allo stesso database che contiene il modello di dati dell'applicazione. L'esercitazione Creazione dello schema di appartenenza in SQL Server ha esaminato l'uso dello strumento aspnet_regsql.exe per raggiungere questo obiettivo.
  3. Personalizzare le impostazioni dell'applicazione Web per fare riferimento al database del passaggio 2. L'esercitazione Creazione dello schema di appartenenza in SQL Server ha illustrato due modi per configurare l'applicazione Web in modo che SqlMembershipProvider userebbe il database selezionato nel passaggio 2: modificando il LocalSqlServer nome del stringa di connessione oppure aggiungendo un nuovo provider registrato all'elenco dei provider del framework di appartenenza e personalizzando tale nuovo provider per l'uso del database dal passaggio 2.

Quando si compila un'applicazione Web che usa SqlMembershipProvider e l'autenticazione basata su form, è necessario eseguire questi tre passaggi prima di usare la classe Membership o i controlli Web di accesso ASP.NET. Poiché questi passaggi sono già stati eseguiti nelle esercitazioni precedenti, è possibile iniziare a usare il framework di appartenenza.

Passaggio 1: Aggiunta di nuove pagine ASP.NET

In questa esercitazione e le tre successive verranno esaminate varie funzioni e funzionalità correlate all'appartenenza. Saranno necessarie una serie di pagine ASP.NET per implementare gli argomenti esaminati in queste esercitazioni. Creiamo queste pagine e poi un file (Web.sitemap) della mappa del sito.

Per iniziare, creare una nuova cartella nel progetto denominato Membership. Aggiungere quindi cinque nuove pagine ASP.NET alla Membership cartella, collegando ogni pagina alla Site.master pagina master. Assegnare un nome alle pagine:

  • CreatingUserAccounts.aspx
  • UserBasedAuthorization.aspx
  • EnhancedCreateUserWizard.aspx
  • AdditionalUserInfo.aspx
  • Guestbook.aspx

A questo punto il Esplora soluzioni del progetto dovrebbe essere simile allo screenshot illustrato nella figura 1.

Sono state aggiunte cinque nuove pagine alla cartella Membership

Figura 1: Sono state aggiunte cinque nuove pagine alla cartella (fare clic per visualizzare l'immagine Membershipa dimensione intera)

A questo punto, ogni pagina deve avere i due controlli Contenuto, uno per ognuno dei ContentPlaceHolders della pagina master: MainContent e LoginContent.

<asp:Content ID="Content1" ContentPlaceHolderID="MainContent"
Runat="Server"> 
</asp:Content> 
<asp:Content ID="Content2" ContentPlaceHolderID="LoginContent"
Runat="Server"> 
</asp:Content>

Tenere presente che il LoginContent markup predefinito di ContentPlaceHolder visualizza un collegamento per accedere o disconnettersi dal sito, a seconda che l'utente sia autenticato. La presenza del Content2 controllo Contenuto, tuttavia, sostituisce il markup predefinito della pagina principale. Come discusso nell'esercitazione "Una panoramica sull'autenticazione basata su form", è utile nelle pagine in cui non vogliamo visualizzare le opzioni di login nella colonna sinistra.

Per queste cinque pagine, tuttavia, si vuole mostrare il markup predefinito della pagina master per LoginContent ContentPlaceHolder. Quindi, rimuovere il markup dichiarativo per il controllo del contenuto Content2. Dopo questa operazione, il markup di ciascuna delle cinque pagine deve contenere un solo controllo Contenuto.

Passaggio 2: Creazione della mappa del sito

Tutti i siti Web più semplici devono implementare una forma di interfaccia utente di navigazione. L'interfaccia utente di navigazione può essere un semplice elenco di collegamenti alle varie sezioni del sito. In alternativa, questi collegamenti possono essere disposti in menu o viste ad albero. Come sviluppatori di pagine, la creazione dell'interfaccia utente di navigazione è solo la metà della storia. Abbiamo anche bisogno di alcuni mezzi per definire la struttura logica del sito in modo gestibile e aggiornabile. Man mano che vengono aggiunte o rimosse pagine esistenti, si vuole essere in grado di aggiornare una singola origine, ovvero la mappa del sito, e di riflettere tali modifiche nell'interfaccia utente di navigazione del sito.

Queste due attività, che definiscono la mappa del sito e implementano un'interfaccia utente di navigazione basata sulla mappa del sito, sono facili da eseguire grazie al framework mappa del sito e ai controlli Web di spostamento aggiunti in ASP.NET versione 2.0. Il framework mappa del sito consente a uno sviluppatore di definire una mappa del sito e quindi di accedervi tramite un'API programmatica (la SiteMap classe ). I controlli Web di spostamento predefiniti includono un controllo Menu, il controllo TreeView e il controllo SiteMapPath.

Analogamente ai framework di abbonamento e ruoli, il framework Site Map è costruito in cima al modello di provider. Il processo della classe del provider Site Map consiste nel generare la struttura in memoria utilizzata dalla SiteMap classe da un archivio dati permanente, ad esempio un file XML o una tabella di database. .NET Framework viene fornito con un provider predefinito di Mappa siti che legge i dati della mappa del sito da un file XML (XmlSiteMapProvider) e questo è il provider che verrà usato in questa esercitazione. Per alcune implementazioni alternative del provider della mappa del sito, consultare la sezione Letture consigliate alla fine di questa guida.

Il provider predefinito della mappa del sito si aspetta che un file XML, denominato Web.sitemap, sia presente nella directory radice. Poiché si usa questo provider predefinito, è necessario aggiungere tale file e definire la struttura della mappa del sito nel formato XML appropriato. Per aggiungere il file, fare clic con il pulsante destro del mouse sul nome del progetto in Esplora soluzioni e scegliere Aggiungi nuovo elemento. Nella finestra di dialogo scegliere di aggiungere un file di tipo Mappa siti denominato Web.sitemap.

Aggiungere un file denominato Web.sitemap alla directory radice del progetto

Figura 2: Aggiungere un file denominato Web.sitemap alla directory radice del progetto (fare clic per visualizzare l'immagine a dimensione intera)

Il file di mappa del sito XML definisce la struttura del sito Web come gerarchia. Questa relazione gerarchica viene modellata nel file XML tramite l'origine degli <siteMapNode> elementi. Il Web.sitemap deve iniziare con un <siteMap> nodo padre che abbia esattamente un <siteMapNode> nodo figlio. Questo elemento di primo livello <siteMapNode> rappresenta la radice della gerarchia e può avere un numero arbitrario di nodi discendenti. Ogni elemento <siteMapNode> deve includere un attributo title e può includere facoltativamente gli attributi url e description, tra gli altri; ogni attributo non vuoto url deve essere univoco.

Immettere il codice XML seguente nel Web.sitemap file:

<?xml version="1.0" encoding="utf-8" ?> 
<siteMap xmlns="http://schemas.microsoft.com/AspNet/SiteMap-File-1.0"> 
 <siteMapNode url="~/Default.aspx" title="Home"> 
 <siteMapNode title="Membership">
 <siteMapNode url="~/Membership/CreatingUserAccounts.aspx" title="Creating User Accounts" /> 
 <siteMapNode url="~/Membership/UserBasedAuthorization.aspx" title="User-Based Authorization" /> 
 <siteMapNode url="~/Membership/Guestbook.aspx" title="Storing Additional User Information" /> 
 </siteMapNode> 
 </siteMapNode> 
</siteMap>

Il markup della mappa del sito precedente definisce la gerarchia illustrata nella figura 3.

La mappa del sito rappresenta una struttura di navigazione gerarchica

Figura 3: La mappa del sito rappresenta una struttura di spostamento gerarchica (fare clic per visualizzare l'immagine a dimensione intera)

Passaggio 3: Aggiornamento della pagina master per includere un'interfaccia utente di spostamento

ASP.NET include numerosi controlli Web correlati allo spostamento per la progettazione di un'interfaccia utente. Sono inclusi i controlli Menu, TreeView e SiteMapPath. I controlli Menu e TreeView eseguono rispettivamente il rendering della struttura della mappa del sito in un menu o in un albero, mentre SiteMapPath visualizza una barra di navigazione che mostra il nodo corrente visitato e i relativi predecessori. I dati della mappa del sito possono essere associati ad altri controlli Web dati tramite SiteMapDataSource e possono essere accessibili a livello di codice tramite la SiteMap classe .

Poiché una descrizione approfondita del framework Mappa del sito e dei controlli di navigazione non rientra nell'ambito di questa serie di esercitazioni, anziché dedicare tempo alla creazione di un'interfaccia utente di navigazione personalizzata, è possibile prendere in prestito quella usata nella Serie di Esercitazioni "Working with Data in ASP.NET 2.0", che usa un controllo Repeater per visualizzare un elenco puntato a due profondità di collegamenti di navigazione, come illustrato nella figura 4.

Per creare questa interfaccia, aggiungere il seguente markup dichiarativo alla Site.master colonna sinistra della pagina master, dove attualmente si trova il testo TODO: Menu sarà qui.

<ul> 
 <li> 
 <asp:HyperLink runat="server" ID="lnkHome" NavigateUrl="~/Default.aspx">Home</asp:HyperLink>
 </li> 
 <asp:Repeater runat="server" ID="menu" DataSourceID="SiteMapDataSource1"> 
 <ItemTemplate>
 <li> 
 <asp:HyperLink ID="lnkMenuItem" runat="server" 
 NavigateUrl='<%# Eval("Url") %>'><%# Eval("Title") %></asp:HyperLink>
 <asp:Repeater ID="submenu" runat="server" DataSource="<%# 
 CType(Container.DataItem, SiteMapNode).ChildNodes %>"> 
 <HeaderTemplate> 
 <ul> 
 </HeaderTemplate> 
 <ItemTemplate>
 <li> 
 <asp:HyperLink ID="lnkMenuItem" 
 runat="server" NavigateUrl='<%#  Eval("Url") %>'><%# Eval("Title") %></asp:HyperLink> 
 </li>
 </ItemTemplate> 
 <FooterTemplate> 
 </ul> 
 </FooterTemplate>
 </asp:Repeater> 
 </li> 
 </ItemTemplate> 
 </asp:Repeater> 
</ul>
<asp:SiteMapDataSource ID="SiteMapDataSource1" runat="server" ShowStartingNode="false"/>

Il markup precedente associa un controllo Repeater denominato menu a siteMapDataSource, che restituisce la gerarchia della mappa del sito definita in Web.sitemap. Poiché la proprietà ShowStartingNode del controllo SiteMapDataSource è impostata su False, inizia a restituire la gerarchia della mappa del sito a partire dai discendenti del nodo Home. Il Repeater visualizza ognuno di questi nodi (attualmente solo Appartenenza) in un elemento <li>. Un altro ripetitore interno visualizza quindi gli elementi figlio del nodo corrente in un elenco annidato non ordinato.

La figura 4 mostra l'output sottoposto a rendering del markup precedente con la struttura della mappa del sito che abbiamo creato nel passaggio 2. Il Repeater esegue il rendering del markup elenco non ordinato semplice; le regole del foglio di stile a cascata definite in Styles.css sono responsabili del layout esteticamente piacevole. Per una descrizione più dettagliata del funzionamento del markup precedente, vedere l'esercitazione Pagine Master e Navigazione Sito.

Il rendering dell'interfaccia utente di navigazione viene eseguito tramite elenchi annidati non ordinati

Figura 4: Viene eseguito il rendering dell'interfaccia utente di navigazione utilizzando elenchi annidati non ordinati (fare clic per visualizzare l'immagine a dimensione intera)

Aggiunta dello spostamento tramite navigazione

Oltre all'elenco di collegamenti nella colonna a sinistra, è anche possibile visualizzare un percorso di navigazione per ogni pagina. Un breadcrumb è un elemento dell'interfaccia utente di navigazione che mostra rapidamente agli utenti la loro posizione corrente all'interno della gerarchia del sito. Il controllo SiteMapPath utilizza la struttura Mappa del Sito per determinare la posizione della pagina corrente nella mappa del sito e visualizza un breadcrumb basato su queste informazioni.

In particolare, aggiungere un elemento <span> all'elemento intestazione <div> della pagina master e impostare l'attributo del nuovo elemento <span>class su breadcrumb. La Styles.css classe contiene una regola per una classe breadcrumb. Quindi, aggiungi un SiteMapPath a questo nuovo <span> elemento.

<div id="header"> 
 <span class="title">User Account Tutorials</span><br /> 
 <span class="breadcrumb"> 
 <asp:SiteMapPath ID="SiteMapPath1" runat="server"> 
 </asp:SiteMapPath> 
 </span> 
</div>

La figura 5 mostra l'output di SiteMapPath quando si visita ~/Membership/CreatingUserAccounts.aspx.

La barra di navigazione visualizza la pagina corrente e i relativi predecessori nella mappa del sito

Figura 5: La barra di navigazione visualizza la pagina corrente e i relativi predecessori nella mappa del sito (fare clic per visualizzare l'immagine a dimensione intera)

Passaggio 4: Rimozione del principale personalizzato e della logica dell'identità

Gli oggetti principal e identità personalizzati possono essere associati all'utente autenticato. A tale scopo, è stato creato un gestore eventi in Global.asax per l'evento dell'applicazione PostAuthenticateRequest , che viene generato dopo l'autenticazione FormsAuthenticationModule dell'utente. In questo gestore eventi, abbiamo sostituito gli oggetti GenericPrincipal e gli FormsIdentity aggiunti da FormsAuthenticationModule con gli oggetti CustomPrincipal e gli CustomIdentity che abbiamo creato in quel tutorial.

Sebbene gli oggetti entità e identità personalizzati siano utili in determinati scenari, nella maggior parte dei casi gli GenericPrincipal oggetti e FormsIdentity sono sufficienti. Di conseguenza, penso che sarebbe opportuno tornare al comportamento predefinito. Apportare questa modifica rimuovendo o commentando il PostAuthenticateRequest gestore eventi o eliminando completamente il Global.asax file.

Nota

Dopo aver commentato o rimosso il codice in Global.asax, sarà necessario commentare il codice nella classe di codice dietro Default.aspx's che esegue il cast della proprietà User.Identity a un'istanza di CustomIdentity.

Passaggio 5: Creazione di un nuovo utente a livello di codice

Per creare un nuovo account utente tramite il framework di appartenenza, usare la classe Membership metodo CreateUser. Questo metodo include parametri di input per il nome utente, la password e altri campi correlati all'utente. Alla chiamata, delega la creazione del nuovo account utente al provider di appartenenze configurato e quindi restituisce un MembershipUser oggetto che rappresenta l'account utente appena creato.

Il CreateUser metodo ha quattro overload, ognuno che accetta un numero diverso di parametri di input:

Questi quattro overload variano in base alla quantità di informazioni raccolte. Il primo overload, ad esempio, richiede solo il nome utente e la password per il nuovo account utente, mentre il secondo richiede anche l'indirizzo di posta elettronica dell'utente.

Questi sovraccarichi esistono perché le informazioni necessarie per creare un nuovo account utente dipendono dalle impostazioni di configurazione del provider di membership. Nell'esercitazione Creazione dello schema di appartenenza in SQL Server, abbiamo esaminato la specifica delle impostazioni di configurazione del provider di appartenenza in Web.config. La tabella 2 includeva un elenco completo delle impostazioni di configurazione.

Un'impostazione di configurazione del provider di appartenenze che influisce sugli CreateUser overload che possono essere usati è l'impostazione requiresQuestionAndAnswer . Se requiresQuestionAndAnswer è impostato su true (impostazione predefinita), quando si crea un nuovo account utente, è necessario specificare una domanda di sicurezza e una risposta. Queste informazioni vengono usate in un secondo momento se l'utente deve reimpostare o modificare la password. In particolare, in quel momento vengono visualizzate le domande di sicurezza e devono immettere la risposta corretta per reimpostare o modificare la password. Di conseguenza, se requiresQuestionAndAnswer è impostato su true , la chiamata di uno dei primi due CreateUser overload genera un'eccezione perché la domanda di sicurezza e la risposta sono mancanti. Poiché l'applicazione è attualmente configurata per richiedere una domanda e una risposta di sicurezza, sarà necessario usare una delle ultime due opzioni di overload durante la creazione dei profili utente a livello di codice.

Per illustrare l'uso del CreateUser metodo , creare un'interfaccia utente in cui viene richiesto all'utente il nome, la password, la posta elettronica e una risposta a una domanda di sicurezza predefinita. Aprire la CreatingUserAccounts.aspx pagina nella Membership cartella e aggiungere i controlli Web seguenti al controllo Contenuto:

  • Un controllo TextBox denominato Username
  • Un controllo TextBox denominato Password, la cui proprietà TextMode è impostata su Password.
  • Un controllo TextBox denominato Email
  • Etichetta denominata SecurityQuestion con la relativa Text proprietà cancellata
  • Un controllo TextBox denominato SecurityAnswer
  • Pulsante denominato CreateAccountButton la cui Text proprietà è impostata su Crea l'account utente
  • Controllo Label denominato CreateAccountResults con la sua proprietà Text svuotata

A questo punto la schermata dovrebbe essere simile alla schermata illustrata nella figura 6.

Aggiungi i vari controlli Web alla pagina CreatingUserAccounts.aspx

Figura 6: Aggiungere i vari controlli Web a CreatingUserAccounts.aspx Page (fare clic per visualizzare l'immagine) a dimensione intera

Label SecurityQuestion e SecurityAnswer TextBox sono progettati per visualizzare una domanda di sicurezza predefinita e raccogliere la risposta dell'utente. Si noti che sia la domanda di sicurezza che la risposta vengono archiviate in base all'utente, quindi è possibile consentire a ogni utente di definire la propria domanda di sicurezza. Tuttavia, per questo esempio ho deciso di usare una domanda di sicurezza universale, vale a dire: Qual è il tuo colore preferito?

Per implementare questa domanda di sicurezza predefinita, aggiungere una costante alla classe code-behind della pagina denominata passwordQuestion, assegnando la domanda di sicurezza. Quindi, nel gestore eventi Page_Load, assegnare questa costante alla proprietà del SecurityQuestion Label Text.

Const passwordQuestion As String = "What is your favorite color"
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load 
 If Not Page.IsPostBack Then 
 SecurityQuestion.Text = passwordQuestion 
 End If 
End Sub

Creare quindi un gestore eventi per l'evento CreateAccountButton' s Click e aggiungere il codice seguente:

Protected Sub CreateAccountButton_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles CreateAccountButton.Click 
 Dim createStatus As MembershipCreateStatus 
 Dim newUser As MembershipUser = _ 
 Membership.CreateUser(Username.Text, Password.Text, _ 
 Email.Text, passwordQuestion, _ 
 SecurityAnswer.Text, True, _ 
 createStatus)
 Select Case createStatus 
 Case MembershipCreateStatus.Success 
 CreateAccountResults.Text = "The user account was successfully created!" 
 Case MembershipCreateStatus.DuplicateUserName 
 CreateAccountResults.Text = "There already exists a user with this username." 
 Case MembershipCreateStatus.DuplicateEmail 
 CreateAccountResults.Text = "There already exists a user with this email address." 
 Case MembershipCreateStatus.InvalidEmail
 CreateAccountResults.Text = "There email address you provided in invalid." 
 Case MembershipCreateStatus.InvalidAnswer 
 CreateAccountResults.Text = "There security answer was invalid." 
 Case MembershipCreateStatus.InvalidPassword 
 CreateAccountResults.Text = "The password you provided is invalid. It must be seven characters long and have at least one non-alphanumeric character." 
 Case Else 
 CreateAccountResults.Text = "There was an unknown error; the user account was NOT created."
 End Select 
End Sub

Il Click gestore eventi inizia definendo una variabile denominata createStatus di tipo MembershipCreateStatus. MembershipCreateStatus è un'enumerazione che indica lo stato dell'operazione CreateUser . Ad esempio, se l'account utente viene creato correttamente, l'istanza risultante MembershipCreateStatus verrà impostata su un valore di Success; , se l'operazione non riesce perché esiste già un utente con lo stesso nome utente, verrà impostato su un valore di DuplicateUserName. Nell'overload che usiamo, è necessario passare un'istanza MembershipCreateStatus nel metodo CreateUser. Questo parametro è impostato sul valore appropriato all'interno del CreateUser metodo ed è possibile esaminarne il valore dopo la chiamata al metodo per determinare se l'account utente è stato creato correttamente.

Dopo aver chiamato CreateUser, passando createStatus, viene usata un'istruzione Select Case per restituire un messaggio appropriato a seconda del valore assegnato a createStatus. La figura 7 mostra l'output quando un nuovo utente è stato creato correttamente. Le figure 8 e 9 mostrano l'output quando l'account utente non viene creato. Nella figura 8 il visitatore ha immesso una password di cinque lettere, che non soddisfa i requisiti di complessità della password specificati nelle impostazioni di configurazione del provider di appartenenze. Nella figura 9 il visitatore sta tentando di creare un account utente con un nome utente esistente (quello creato nella figura 7).

Viene creato un nuovo account utente

Figura 7: Creazione di un nuovo account utente (fare clic per visualizzare l'immagine a dimensione intera)

L'account utente non viene creato perché la password specificata è troppo debole

Figura 8: L'account utente non viene creato perché la password specificata è troppo debole (fare clic per visualizzare l'immagine a dimensione intera)

L'account utente non viene creato perché il nome utente è già in uso

Figura 9: L'account utente non viene creato perché il nome utente è già in uso (fare clic per visualizzare l'immagine a dimensione intera)

Nota

Ci si potrebbe chiedere come determinare l'esito positivo o negativo quando si usa uno dei primi due CreateUser overload del metodo, nessuno dei quali ha un parametro di tipo MembershipCreateStatus. Questi primi due overload generano un'eccezione MembershipCreateUserException in caso di fallimento, includendo una proprietà StatusCode di tipo MembershipCreateStatus.

Dopo aver creato alcuni account utente, verificare che gli account siano stati creati elencando il contenuto delle aspnet_Users tabelle e aspnet_Membership nel SecurityTutorials.mdf database. Come illustrato nella figura 10, ho aggiunto due utenti tramite la CreatingUserAccounts.aspx pagina: Tito e Bruce.

Ci sono due utenti nell'archivio di utenti membri: Tito e Bruce

Figura 10: Ci sono due utenti nell'Archivio utenti di appartenenza: Tito e Bruce (Fare clic per visualizzare l'immagine a dimensione intera)

Mentre l'archivio utenti di appartenenza include ora le informazioni sull'account di Bruce e Tito, dobbiamo ancora implementare funzionalità che consentono a Bruce o Tito di accedere al sito. Attualmente, Login.aspx convalida le credenziali dell'utente rispetto a un set predefinito di coppie nome utente/password - non convalida le credenziali fornite rispetto al framework di membership. Per il momento, la visualizzazione dei nuovi account utente nelle aspnet_Users tabelle e aspnet_Membership dovrà essere sufficiente. Nell'esercitazione successiva, Convalida delle credenziali utente rispetto al Membership User Store, aggiorneremo la pagina di accesso per convalidare le credenziali rispetto al Membership Store.

Nota

Se non vengono visualizzati utenti nel SecurityTutorials.mdf database, è possibile che l'applicazione Web usi il provider di appartenenza predefinito, AspNetSqlMembershipProvider, che usa il ASPNETDB.mdf database come archivio utenti. Per determinare se si tratta del problema, fare clic sul pulsante Aggiorna nella Esplora soluzioni. Se un database denominato ASPNETDB.mdf è stato aggiunto alla cartella App_Data, questo è il problema. Tornare al passaggio 4 dell'esercitazione Creazione dello schema di appartenenza in SQL Server per istruzioni su come configurare correttamente il provider di appartenenze.

Nella maggior parte degli scenari di creazione dell'account utente, il visitatore viene presentato con un'interfaccia per immettere il nome utente, la password, la posta elettronica e altre informazioni essenziali, a questo punto viene creato un nuovo account. In questo passaggio è stato esaminato come creare un'interfaccia di questo tipo a mano e quindi si è visto come usare il Membership.CreateUser metodo per aggiungere il nuovo account utente a livello di codice in base agli input dell'utente. Il codice, tuttavia, ha appena creato il nuovo account utente. Non ha eseguito alcuna azione di completamento, ad esempio l'accesso dell'utente al sito con l'account utente appena creato o l'invio di un messaggio di posta elettronica di conferma all'utente. Questi passaggi aggiuntivi richiedono codice aggiuntivo nel gestore eventi del Click pulsante.

ASP.NET viene fornito con il controllo CreateUserWizard, progettato per gestire il processo di creazione dell'account utente, dal rendering di un'interfaccia utente per la creazione di nuovi account utente, alla creazione dell'account nel framework di appartenenza e all'esecuzione di attività di creazione post-account, ad esempio l'invio di un messaggio di posta elettronica di conferma e la registrazione dell'utente appena creato nel sito. L'uso del controllo CreateUserWizard è semplice come trascinare il controllo CreateUserWizard dalla casella degli strumenti in una pagina e quindi impostare alcune proprietà. Nella maggior parte dei casi, non è necessario scrivere una singola riga di codice. Questo ingegnoso controllo verrà esaminato in dettaglio nella fase 6.

Se i nuovi account utente vengono creati solo tramite una tipica pagina Web Crea account, è improbabile che sia necessario scrivere codice che usi il CreateUser metodo, perché il controllo CreateUserWizard probabilmente soddisfa le proprie esigenze. Tuttavia, il CreateUser metodo è utile negli scenari in cui è necessaria un'esperienza utente di creazione account altamente personalizzata o quando è necessario creare nuovi account utente a livello di codice tramite un'interfaccia alternativa. Ad esempio, potrebbe essere presente una pagina che consente a un utente di caricare un file XML contenente informazioni utente da un'altra applicazione. La pagina può analizzare il contenuto del file XML caricato e creare un nuovo account per ogni utente rappresentato nel codice XML chiamando il CreateUser metodo .

Passaggio 6: Creazione di un nuovo utente con il controllo CreateUserWizard

ASP.NET viene fornito con diversi controlli Web di accesso. Questi controlli facilitano molti scenari comuni relativi all'account utente e all'account di accesso. Il controllo CreateUserWizard è un controllo di questo tipo progettato per presentare un'interfaccia utente per l'aggiunta di un nuovo account utente al framework di appartenenza.

Come molti degli altri controlli Web correlati all'account di accesso, è possibile usare CreateUserWizard senza scrivere una singola riga di codice. Fornisce intuitivamente un'interfaccia utente basata sulle impostazioni di configurazione del provider di membri e chiama internamente il metodo della classe CreateUser dopo che l'utente ha immesso le informazioni necessarie e cliccato sul pulsante Crea utente. Il controllo CreateUserWizard è estremamente personalizzabile. Ci sono un'ampia gamma di eventi che si attivano durante varie fasi del processo di creazione dell'account. È possibile creare gestori eventi, in base alle esigenze, per inserire logica personalizzata nel flusso di lavoro di creazione dell'account. Inoltre, l'aspetto di CreateUserWizard è molto flessibile. Esistono diverse proprietà che definiscono l'aspetto dell'interfaccia predefinita; se necessario, il controllo può essere convertito in un modello o in passaggi di registrazione utente aggiuntivi.

Si inizierà con un'analisi dell'interfaccia e del comportamento predefiniti del controllo CreateUserWizard. Si esaminerà quindi come personalizzare l'aspetto tramite le proprietà e gli eventi del controllo.

Esame dell'interfaccia e del comportamento predefiniti di CreateUserWizard

Tornare alla CreatingUserAccounts.aspx pagina nella Membership cartella, passare alla modalità Progettazione o Divisione e quindi aggiungere un controllo CreateUserWizard nella parte superiore della pagina. Il controllo CreateUserWizard viene archiviato nella sezione Controlli di accesso della casella degli strumenti. Dopo aver aggiunto il controllo, impostarne la ID proprietà su RegisterUser. Come illustrato nella figura 11, la CreateUserWizard esegue il rendering di un'interfaccia con caselle di testo per il nome utente, la password, l'indirizzo di posta elettronica e la risposta del nuovo utente.

Il controllo CreateUserWizard esegue il rendering di un'interfaccia utente di creazione generica

Figura 11: Il controllo CreateUserWizard esegue il rendering di un'interfaccia utente di creazione generica (fare clic per visualizzare l'immagine a dimensione intera)

Diamo un po' di tempo per confrontare l'interfaccia utente predefinita generata dal controllo CreateUserWizard con l'interfaccia creata nel passaggio 5. Per iniziare, il controllo CreateUserWizard consente al visitatore di specificare sia la domanda di sicurezza che la risposta, mentre l'interfaccia creata manualmente ha usato una domanda di sicurezza predefinita. L'interfaccia del controllo CreateUserWizard include anche controlli di convalida, mentre era ancora necessario implementare la convalida nei campi modulo dell'interfaccia. E l'interfaccia di controllo CreateUserWizard include una casella di testo Confirm Password (insieme a CompareValidator) per assicurarsi che il testo immesso nelle caselle di testo Password e Confronta password sia uguale.

Quello che è interessante è che il controllo CreateUserWizard consulta le impostazioni di configurazione del provider Membership per il rendering dell'interfaccia utente. Ad esempio, le caselle di testo domande e risposte di sicurezza vengono visualizzate solo se requiresQuestionAndAnswer è impostata su True. Analogamente, il controllo CreateUserWizard aggiunge automaticamente un RegularExpressionValidator per assicurarsi che i requisiti di complessità della password siano soddisfatti e imposta le proprietà ErrorMessage e ValidationExpression in base alle impostazioni di configurazione minRequiredPasswordLength, minRequiredNonalphanumericCharacters e passwordStrengthRegularExpression.

Il controllo CreateUserWizard, come suggerisce il nome, è derivato dal controllo Wizard. I controlli della procedura guidata sono progettati per fornire un'interfaccia per completare attività in più passaggi. Un controllo Procedura guidata può avere un numero arbitrario di WizardSteps, ognuno dei quali è un modello che definisce i controlli HTML e Web per ciascun passaggio. Il controllo Procedura guidata visualizza inizialmente il primo WizardStep, insieme ai controlli di spostamento che consentono all'utente di procedere da un passaggio all'altro o di tornare ai passaggi precedenti.

Come illustrato nel markup dichiarativo nella figura 11, l'interfaccia predefinita del controllo CreateUserWizard include due elementi WizardStep.

  • CreateUserWizardStep ? esegue il rendering dell'interfaccia per raccogliere informazioni per la creazione del nuovo account utente. Questo è il passaggio illustrato nella figura 11.
  • CompleteWizardStep ? visualizza un messaggio che indica che l'account è stato creato correttamente.

L'aspetto e il comportamento di CreateUserWizard possono essere modificati convertendo uno di questi passaggi in modelli o aggiungendo i propri WizardStep elementi. Si esaminerà l'aggiunta di un WizardStep all'interfaccia di registrazione nell'esercitazione Archiviazione di informazioni utente aggiuntive.

Vediamo il controllo CreateUserWizard in azione. Visitare la CreatingUserAccounts.aspx pagina tramite un browser. Per iniziare, immettere alcuni valori non validi nell'interfaccia di CreateUserWizard. Provare a immettere una password non conforme ai requisiti di complessità della password o lasciare vuota la casella di testo Nome utente. CreateUserWizard visualizzerà un messaggio di errore appropriato. La figura 12 mostra l'output quando si tenta di creare un utente con una password non sufficientemente forte.

CreateUserWizard inserisce automaticamente i controlli di convalida

Figura 12: CreateUserWizard inserisce automaticamente i controlli di convalida (fare clic per visualizzare l'immagine a dimensione intera)

Immettere quindi i valori appropriati in CreateUserWizard e fare clic sul pulsante Crea utente. Supponendo che i campi richiesti siano stati immessi e che il livello di attendibilità della password sia sufficiente, il CreateUserWizard creerà un nuovo account utente tramite il framework di Membership e quindi visualizzerà l'interfaccia di CompleteWizardStep (vedere la figura 13). Dietro le quinte, il metodo Membership.CreateUser viene chiamato da CreateUserWizard, proprio come abbiamo fatto nel passaggio 5.

È stato creato un nuovo account utente

Figura 13: È stato creato un nuovo account utente (fare clic per visualizzare l'immagine a dimensione intera)

Nota

Come illustrato nella figura 13, l'interfaccia CompleteWizardStepdi include un pulsante Continua. Tuttavia, a questo punto facendo clic si esegue solo un postback, lasciando il visitatore nella stessa pagina. Nella sezione Personalizzazione dell'aspetto e del comportamento di CreateUserWizard tramite le relative proprietà verrà illustrato come è possibile fare in modo che questo pulsante invii il visitatore a Default.aspx (o un'altra pagina).

Dopo aver creato un nuovo account utente, tornare a Visual Studio ed esaminare le aspnet_Users tabelle e aspnet_Membership come nella figura 10 per verificare che l'account sia stato creato correttamente.

Personalizzazione del comportamento e dell'aspetto di CreateUserWizard tramite le relative proprietà

CreateUserWizard può essere personalizzato in diversi modi, tramite proprietà, WizardStep s e gestori eventi. In questa sezione verrà illustrato come personalizzare l'aspetto del controllo tramite le relative proprietà; la sezione successiva esamina l'estensione del comportamento del controllo tramite gestori eventi.

Praticamente tutto il testo visualizzato nell'interfaccia utente predefinita del controllo CreateUserWizard può essere personalizzato tramite la sua pletora di proprietà. Ad esempio, le etichette Nome utente, Password, Conferma password, Posta elettronica, Domanda di sicurezza e Risposta di sicurezza visualizzate a sinistra delle caselle di testo possono essere personalizzate rispettivamente dalle UserNameLabelTextproprietà , PasswordLabelTextConfirmPasswordLabelText, EmailLabelTextQuestionLabelText, , e AnswerLabelText . Analogamente, sono disponibili proprietà per specificare il testo per i pulsanti Crea utente e Continua in CreateUserWizardStep e CompleteWizardStep, nonché se questi pulsanti vengono visualizzati come Pulsanti, LinkButton o ImageButtons.

I colori, i bordi, i tipi di carattere e altri elementi visivi sono configurabili tramite una serie di proprietà di stile. Il controllo CreateUserWizard ha le proprietà comuni dello stile del controllo Web , BackColor, BorderStyleCssClass, Fonte così via, e sono disponibili diverse proprietà di stile per definire l'aspetto per sezioni specifiche dell'interfaccia di CreateUserWizard. La TextBoxStyle proprietà, ad esempio, definisce gli stili per le caselle di testo in CreateUserWizardStep, mentre la TitleTextStyle proprietà definisce lo stile per il titolo ( Iscrizione per il nuovo account ).

Oltre alle proprietà correlate all'aspetto, esistono diverse proprietà che influiscono sul comportamento del controllo CreateUserWizard. La DisplayCancelButton proprietà, se impostata su True, visualizza un pulsante Annulla accanto al pulsante Crea utente (il valore predefinito è False). Se si visualizza il pulsante Annulla, assicurarsi di impostare anche la CancelDestinationPageUrl proprietà , che specifica la pagina a cui l'utente viene inviato dopo aver fatto clic su Annulla. Come indicato nella sezione precedente, il pulsante Continua nell'interfaccia CompleteWizardStep provoca un postback, ma lascia il visitatore nella stessa pagina. Per inviare il visitatore ad altre pagine dopo aver fatto clic sul pulsante Continua, è sufficiente specificare l'URL nella ContinueDestinationPageUrl proprietà .

Aggiornare il RegisterUser controllo CreateUserWizard per visualizzare un pulsante Annulla e inviare il visitatore a Default.aspx quando si fa clic sui pulsanti Annulla o Continua. A tale scopo, impostare la proprietà DisplayCancelButton su True ed entrambe le proprietà CancelDestinationPageUrl e ContinueDestinationPageUrl su ~/Default.aspx. La figura 14 mostra l'elemento CreateUserWizard aggiornato quando visualizzato tramite un browser.

CreateUserWizardStep include un pulsante Annulla

Figura 14: Il CreateUserWizardStep include un pulsante Annulla (fare clic per visualizzare l'immagine a dimensione intera)

Quando un visitatore immette un nome utente, una password, un indirizzo di posta elettronica e una risposta di sicurezza e fa clic su Crea utente, viene creato un nuovo account utente e il visitatore viene connesso come utente appena creato. Supponendo che la persona che visita la pagina stia creando un nuovo account per se stessi, questo è probabilmente il comportamento desiderato. Tuttavia, è possibile consentire agli amministratori di aggiungere nuovi account utente. In questo modo, l'account utente verrà creato, ma l'amministratore rimarrà connesso come amministratore (e non come account appena creato). Questo comportamento può essere modificato tramite la proprietà LoginCreatedUser.

Gli account utente nel framework di appartenenza contengono un flag approvato; gli utenti che non sono approvati non sono in grado di accedere al sito. Per impostazione predefinita, un account appena creato viene contrassegnato come approvato, consentendo all'utente di accedere immediatamente al sito. È tuttavia possibile che i nuovi account utente siano contrassegnati come non approvati. Forse si vuole che un amministratore approvi manualmente nuovi utenti prima di poter accedere; o forse si vuole verificare che l'indirizzo di posta elettronica immesso all'iscrizione sia valido prima di consentire a un utente di accedere. Indipendentemente dal caso, è possibile che l'account utente appena creato sia contrassegnato come non approvato impostando la proprietàDisableCreatedUser controllo CreateUserWizard su True (il valore predefinito è False).

Altre proprietà correlate al comportamento della nota includono AutoGeneratePassword e MailDefinition. Se la AutoGeneratePassword proprietà è impostata su True, le CreateUserWizardStep caselle di testo Password e Conferma password non vengono visualizzate, ma la password dell'utente appena creata viene generata automaticamente usando il Membership metodoGeneratePassword classe . Il GeneratePassword metodo costruisce una password di lunghezza specificata e con un numero sufficiente di caratteri non alfanumerici per soddisfare i requisiti di complessità della password configurati.

La MailDefinition proprietà è utile se si desidera inviare un messaggio di posta elettronica all'indirizzo di posta elettronica specificato durante il processo di creazione dell'account. La MailDefinition proprietà include una serie di proprietà secondarie per la definizione di informazioni sul messaggio di posta elettronica costruito. Queste sottoproprietà includono opzioni come Subject, PriorityIsBodyHtml, From, CCe BodyFileName. La BodyFileName proprietà punta a un file HTML o di testo che contiene il corpo del messaggio di posta elettronica. Il corpo supporta due segnaposto predefiniti: <%UserName%> e <%Password%>. Questi segnaposto, se presenti nel BodyFileName file, verranno sostituiti con il nome e la password dell'utente appena creati.

Nota

La CreateUserWizard proprietà del MailDefinition controllo specifica solo i dettagli relativi al messaggio di posta elettronica inviato quando viene creato un nuovo account. Non include dettagli sul modo in cui il messaggio di posta elettronica viene effettivamente inviato ( ovvero se viene usata una directory smtp server o di rilascio della posta elettronica, eventuali informazioni di autenticazione e così via). Questi dettagli di basso livello devono essere definiti nella <system.net> sezione in Web.config. Per altre informazioni su queste impostazioni di configurazione e sull'invio di messaggi di posta elettronica da ASP.NET 2.0 in generale, vedere le domande frequenti all'indirizzo SystemNetMail.com e all'articolo Invio di messaggi di posta elettronica in ASP.NET 2.0.

Estensione del comportamento di CreateUserWizard tramite gestori eventi

Il controllo CreateUserWizard genera un numero di eventi durante il flusso di lavoro. Ad esempio, dopo che un visitatore immette il nome utente, la password e altre informazioni pertinenti e fa clic sul pulsante Crea utente, il controllo CreateUserWizard genera il relativo CreatingUser evento. Se si verifica un problema durante il processo di creazione, viene generato l'eventoCreateUserError, ma se l'utente viene creato correttamente, viene sollevato l'eventoCreatedUser. Sono disponibili altri eventi di controllo CreateUserWizard che vengono generati, ma questi sono i tre più pertinenti.

In alcuni scenari è possibile usare il flusso di lavoro CreateUserWizard, che è possibile eseguire creando un gestore eventi per l'evento appropriato. Per illustrare questo problema, è possibile migliorare il RegisterUser controllo CreateUserWizard per includere una convalida personalizzata per il nome utente e la password. In particolare, è possibile migliorare createUserWizard in modo che i nomi utente non possano contenere spazi iniziali o finali e il nome utente non possa essere visualizzato in qualsiasi punto della password. In breve, vogliamo impedire a qualcuno di creare un nome utente come "Scott" o avere una combinazione di nome utente/password come Scott e Scott.1234 .

A tale scopo, verrà creato un gestore eventi per l'evento CreatingUser per eseguire i controlli di convalida aggiuntivi. Se i dati forniti non sono validi, è necessario annullare il processo di creazione. È anche necessario aggiungere un controllo Web Label alla pagina per visualizzare un messaggio che indica che il nome utente o la password non sono validi. Per iniziare, aggiungere un controllo Label sotto il controllo CreateUserWizard, impostandone la ID proprietà su InvalidUserNameOrPasswordMessage e la relativa ForeColor proprietà su Red. Svuotare la sua proprietà Text e impostare le proprietà EnableViewState e Visible su False.

<asp:Label runat="server"" id="InvalidUserNameOrPasswordMessage"
 Visible="false" ForeColor="Red" EnableViewState="false"> 
</asp:Label>

Creare quindi un gestore eventi per l'evento del CreatingUser controllo CreateUserWizard. Per creare un gestore eventi, selezionare il controllo in Progettazione e quindi passare al Finestra Proprietà. Fare clic sull'icona del fulmine e quindi fare doppio clic sull'evento appropriato per creare il gestore eventi.

Aggiungere il codice seguente al gestore eventi CreatingUser :

Protected Sub RegisterUser_CreatingUser(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.LoginCancelEventArgs) Handles RegisterUser.CreatingUser
 Dim trimmedUserName As String = RegisterUser.UserName.Trim() 
 If RegisterUser.UserName.Length <> trimmedUserName.Length Then 
 ' Show the error message 
 InvalidUserNameOrPasswordMessage.Text = "The username cannot contain leading or trailing spaces." 
 InvalidUserNameOrPasswordMessage.Visible = True 
 ' Cancel the create user workflow 
 e.Cancel = True 
 Else 
 ' Username is valid, make sure that the password does not contain the username 
 If RegisterUser.Password.IndexOf(RegisterUser.UserName, StringComparison.OrdinalIgnoreCase) >= 0 Then 
 ' Show the error message 
 InvalidUserNameOrPasswordMessage.Text = "The username may not appear anywhere in the password." 
 InvalidUserNameOrPasswordMessage.Visible = True 
 ' Cancel the create user workflow 
 e.Cancel = True 
 End If 
 End If 
End Sub

Si noti che il nome utente e la password immessi nel controllo CreateUserWizard sono disponibili rispettivamente tramite le relative UserName proprietàPassword . Queste proprietà vengono usate nel gestore eventi precedente per determinare se il nome utente specificato contiene spazi iniziali o finali e se il nome utente viene trovato all'interno della password. Se una di queste condizioni viene soddisfatta, viene visualizzato un messaggio di errore nell'etichetta InvalidUserNameOrPasswordMessage e la proprietà del e.Cancel gestore eventi è impostata su True. Se e.Cancel è impostato su True, CreateUserWizard interrompe il flusso di lavoro, annullando efficacemente il processo di creazione dell'account utente.

La figura 15 mostra una schermata di CreatingUserAccounts.aspx quando l'utente immette un nome utente con spazi iniziali.

I nomi utente con spazi iniziali o finali non sono consentiti

Figura 15: I nomi utente con spazi iniziali o finali non sono consentiti (fare clic per visualizzare l'immagine a dimensione intera)

Nota

Nell'esercitazione Archiviazione di informazioni aggiuntive sull'utente verrà esemplificato l'uso dell'evento CreatedUser del controllo CreateUserWizard.

Riepilogo

Il Membership metodo della CreateUser classe crea un nuovo account utente nel framework Membership. A tale scopo, delegando la chiamata al provider di appartenenze configurato. Nel caso di SqlMembershipProvider, il CreateUser metodo aggiunge un record alle tabelle di aspnet_Users database e aspnet_Membership .

Anche se i nuovi account utente possono essere creati a livello di codice (come illustrato nel passaggio 5), un approccio più rapido e semplice consiste nell'usare il controllo CreateUserWizard. Questo controllo fornisce un'interfaccia utente a più fasi per la raccolta di informazioni utente e la creazione di un nuovo utente nel framework di gestione utenti. Sotto le quinte, questo controllo usa lo stesso Membership.CreateUser metodo esaminato nel passaggio 5, ma il controllo crea l'interfaccia utente, i controlli di convalida e risponde agli errori di creazione dell'account utente senza dover scrivere un lick di codice.

A questo punto è disponibile la funzionalità per creare nuovi account utente. Tuttavia, la pagina di login continua a verificare le credenziali codificate specificate nel secondo tutorial. Nell'esercitazione successiva aggiorneremo Login.aspx per convalidare le credenziali fornite dall'utente nel framework di appartenenza.

Buon programmatori!

Altre informazioni

Per altre informazioni sugli argomenti illustrati in questa esercitazione, vedere le risorse seguenti:

Informazioni sull'autore

Scott Mitchell, autore di più libri ASP/ASP.NET e fondatore di 4GuysFromRolla.com, ha lavorato con le tecnologie Web Microsoft dal 1998. Scott lavora come consulente indipendente, formatore e scrittore. Il suo ultimo libro è Sams Teach Yourself ASP.NET 2.0 in 24 ore. Scott può essere raggiunto all'indirizzo mitchell@4guysfromrolla.com o tramite il suo blog all'indirizzo http://ScottOnWriting.NET.

Grazie speciale a

Questa serie di esercitazioni è stata esaminata da diversi revisori validi. Il revisore principale per questo tutorial è stato Teresa Murphy. Si è interessati a esaminare i prossimi articoli MSDN? Se sì, scrivimi a mitchell@4GuysFromRolla.com.