Condividi tramite


Assegnazione di ruoli agli utenti (VB)

di Scott Mitchell

Nota

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

  • Prestazioni migliori
  • Miglioramento dell'estendibilità e della testability
  • 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 verranno create due pagine ASP.NET per facilitare la gestione degli utenti appartenenti ai ruoli. La prima pagina includerà le funzionalità per visualizzare gli utenti appartenenti a un determinato ruolo, i ruoli a cui appartiene un determinato utente e la possibilità di assegnare o rimuovere un determinato utente da un determinato ruolo. Nella seconda pagina si aumenta il controllo CreateUserWizard in modo che includa un passaggio per specificare i ruoli a cui appartiene l'utente appena creato. Ciò è utile negli scenari in cui un amministratore è in grado di creare nuovi account utente.

Introduzione

L'esercitazione precedente ha esaminato il framework Roles e . SqlRoleProviderÈ stato illustrato come usare la Roles classe per creare, recuperare ed eliminare ruoli. Oltre a creare ed eliminare ruoli, è necessario essere in grado di assegnare o rimuovere utenti da un ruolo. Sfortunatamente, ASP.NET non viene fornito con controlli Web per la gestione di quali ruoli appartengono gli utenti. È invece necessario creare pagine ASP.NET personalizzate per gestire queste associazioni. La buona notizia è che l'aggiunta e la rimozione di utenti ai ruoli è piuttosto semplice. La Roles classe contiene diversi metodi per aggiungere uno o più utenti a uno o più ruoli.

In questa esercitazione verranno create due pagine ASP.NET per facilitare la gestione degli utenti appartenenti ai ruoli. La prima pagina includerà le funzionalità per visualizzare gli utenti appartenenti a un determinato ruolo, i ruoli a cui appartiene un determinato utente e la possibilità di assegnare o rimuovere un determinato utente da un determinato ruolo. Nella seconda pagina si aumenta il controllo CreateUserWizard in modo che includa un passaggio per specificare i ruoli a cui appartiene l'utente appena creato. Ciò è utile negli scenari in cui un amministratore è in grado di creare nuovi account utente.

È possibile iniziare subito.

Elenco degli utenti appartenenti ai ruoli

Il primo ordine aziendale per questa esercitazione consiste nel creare una pagina Web da cui gli utenti possono essere assegnati ai ruoli. Prima di preoccuparsi di come assegnare gli utenti ai ruoli, è necessario innanzitutto concentrarsi su come determinare quali utenti appartengono ai ruoli. Esistono due modi per visualizzare queste informazioni: "per ruolo" o "per utente". È possibile consentire al visitatore di selezionare un ruolo e quindi visualizzarli tutti gli utenti che appartengono al ruolo (visualizzazione "per ruolo") oppure chiedere al visitatore di selezionare un utente e quindi visualizzarli i ruoli assegnati a tale utente (visualizzazione "by user").

La visualizzazione "per ruolo" è utile nelle circostanze in cui il visitatore vuole conoscere il set di utenti che appartengono a un determinato ruolo; la visualizzazione "by user" è ideale quando il visitatore deve conoscere i ruoli di un utente specifico. Nella pagina sono incluse sia le interfacce "per ruolo" che "per utente".

Si inizierà con la creazione dell'interfaccia "per utente". Questa interfaccia sarà costituita da un elenco a discesa e da un elenco di caselle di controllo. L'elenco a discesa verrà popolato con il set di utenti nel sistema; le caselle di controllo enumereranno i ruoli. Se si seleziona un utente dall'elenco a discesa, tali ruoli appartengono all'utente. La persona che visita la pagina può quindi selezionare o deselezionare le caselle di controllo per aggiungere o rimuovere l'utente selezionato dai ruoli corrispondenti.

Nota

L'uso di un elenco a discesa per elencare gli account utente non è una scelta ideale per i siti Web in cui potrebbero esserci centinaia di account utente. Un elenco a discesa è progettato per consentire a un utente di selezionare un elemento da un elenco relativamente breve di opzioni. Diventa rapidamente difficile man mano che aumenta il numero di elementi dell'elenco. Se si sta creando un sito Web con un numero potenzialmente elevato di account utente, è possibile prendere in considerazione l'uso di un'interfaccia utente alternativa, ad esempio un'interfaccia GridView visualizzabile da pagina o un'interfaccia filtrabile che elenca il visitatore di scegliere una lettera e quindi mostra solo gli utenti il cui nome utente inizia con la lettera selezionata.

Passaggio 1: Creazione dell'interfaccia utente "By User"

Aprire la UsersAndRoles.aspx pagina. Nella parte superiore della pagina aggiungere un controllo Web Etichetta denominato ActionStatus e cancellarne la Text proprietà. Useremo questa etichetta per fornire commenti e suggerimenti sulle azioni eseguite, visualizzando messaggi come "User Tito è stato aggiunto al ruolo Administrators" o "User Jisun è stato rimosso dal ruolo Supervisors". Per far risaltare questi messaggi, impostare la proprietà dell'etichetta CssClass su "Importante".

<p align="center"> 
     <asp:Label ID="ActionStatus" runat="server" CssClass="Important"> </asp:Label> 
</p>

Aggiungere quindi la definizione di classe CSS seguente al Styles.css foglio di stile:

.Important 
{ 
     font-size: large; 
     color: Red; 
}

Questa definizione CSS indica al browser di visualizzare l'etichetta utilizzando un tipo di carattere rosso di grandi dimensioni. La figura 1 mostra questo effetto tramite il Designer di Visual Studio.

La proprietà CssClass dell'etichetta restituisce un tipo di carattere rosso di grandi dimensioni

Figura 1: La proprietà dell'etichetta CssClass restituisce un tipo di carattere grande e rosso (fare clic per visualizzare l'immagine a dimensione intera)

Aggiungere quindi un oggetto DropDownList alla pagina, impostarne la ID proprietà UserListsu e impostarne la AutoPostBack proprietà su True. Useremo questo elenco a discesa per elencare tutti gli utenti nel sistema. Questo oggetto DropDownList verrà associato a una raccolta di oggetti MembershipUser. Poiché si vuole che DropDownList visualizzi la proprietà UserName dell'oggetto MembershipUser (e usarla come valore degli elementi dell'elenco), impostare le proprietà e DataValueField di DataTextField DropDownList su "UserName".

Sotto DropDownList aggiungere un repeater denominato UsersRoleList. Questo ripetitore elenca tutti i ruoli nel sistema come una serie di caselle di controllo. Definire il repeater ItemTemplate usando il markup dichiarativo seguente:

<asp:Repeater ID="UsersRoleList" runat="server"> 
     <ItemTemplate> 
          <asp:CheckBox runat="server" ID="RoleCheckBox" AutoPostBack="true" 
               Text='<%# Container.DataItem %>' /> 
          <br /> 
     </ItemTemplate> 
</asp:Repeater>

Il ItemTemplate markup include un singolo controllo Web CheckBox denominato RoleCheckBox. La proprietà di AutoPostBack CheckBox è impostata su True e la Text proprietà è associata a Container.DataItem. Il motivo per cui la sintassi di associazione dati è semplicemente Container.DataItem perché il framework Roles restituisce l'elenco di nomi di ruolo come matrice di stringhe ed è questa matrice di stringhe che verrà associata al Repeater. Una descrizione completa del motivo per cui questa sintassi viene usata per visualizzare il contenuto di una matrice associata a un controllo Web dati esula dall'ambito di questa esercitazione. Per altre informazioni su questo argomento, vedere Associazione di una matrice scalare a un controllo Web dati.

A questo punto il markup dichiarativo dell'interfaccia "by user" dovrebbe essere simile al seguente:

<h3>Manage Roles By User</h3> 
<p> 
     <b>Select a User:</b> 
     <asp:DropDownList ID="UserList" runat="server" AutoPostBack="True" 
          DataTextField="UserName" DataValueField="UserName"> 
     </asp:DropDownList> 
</p> 
<p> 
     <asp:Repeater ID="UsersRoleList" runat="server"> 
          <ItemTemplate> 
               <asp:CheckBox runat="server" ID="RoleCheckBox" AutoPostBack="true" 
                    Text='<%# Container.DataItem %>' /> 
               <br /> 
          </ItemTemplate> 
     </asp:Repeater> 
</p>

È ora possibile scrivere il codice per associare il set di account utente a DropDownList e al set di ruoli a Repeater. Nella classe code-behind della pagina aggiungere un metodo denominato e un altro denominato BindUsersToUserListBindRolesListusando il codice seguente:

Private Sub BindUsersToUserList() 
     ' Get all of the user accounts 
     Dim users As MembershipUserCollection = Membership.GetAllUsers() 
     UserList.DataSource = users 
     UserList.DataBind() 
End Sub 
 
Private Sub BindRolesToList() 
     ' Get all of the roles 
     Dim roleNames() As String = Roles.GetAllRoles() 
     UsersRoleList.DataSource = roleNames 
     UsersRoleList.DataBind() 
End Sub

Il BindUsersToUserList metodo recupera tutti gli account utente nel sistema tramite il Membership.GetAllUsers metodo . Restituisce un MembershipUserCollection oggetto , che è una raccolta di MembershipUser istanze. Questa raccolta viene quindi associata all'oggetto UserList DropDownList. Le MembershipUser istanze che trucco la raccolta contengono un'ampia gamma di proprietà, ad esempio UserName, Email, CreationDatee IsOnline. Per indicare a DropDownList di visualizzare il valore della UserName proprietà, assicurarsi che le UserList proprietà e DataValueField di DataTextField DropDownList siano state impostate su "UserName".

Nota

Il Membership.GetAllUsers metodo ha due overload: uno che non accetta parametri di input e restituisce tutti gli utenti e uno che accetta valori interi per l'indice di pagina e le dimensioni della pagina e restituisce solo il sottoinsieme specificato degli utenti. Quando sono presenti grandi quantità di account utente visualizzati in un elemento dell'interfaccia utente visualizzabile, il secondo overload può essere usato per visualizzare in modo più efficiente gli utenti perché restituisce solo il subset preciso di account utente anziché tutti.

Il BindRolesToList metodo inizia chiamando il Roles metodo della GetAllRolesclasse , che restituisce una matrice di stringhe contenente i ruoli nel sistema. Questa matrice di stringhe viene quindi associata al Repeater.

Infine, è necessario chiamare questi due metodi quando la pagina viene caricata per la prima volta. Aggiungere il codice seguente al gestore eventi Page_Load :

Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load 
     If Not Page.IsPostBack Then 
          ' Bind the users and roles 
          BindUsersToUserList() 
          BindRolesToList() 
     End If 
End Sub

Con questo codice sul posto, visitare la pagina tramite un browser; la schermata dovrebbe essere simile alla figura 2. Tutti gli account utente vengono popolati nell'elenco a discesa e, sotto di esso, ogni ruolo viene visualizzato come casella di controllo. Poiché le proprietà di DropDownList e CheckBoxes vengono impostate AutoPostBack su True, la modifica dell'utente selezionato o il controllo o l'annullamento della selezione di un ruolo causa un postback. Non viene eseguita alcuna azione, tuttavia, perché è ancora necessario scrivere codice per gestire queste azioni. Queste attività verranno affrontate nelle due sezioni successive.

Nella pagina vengono visualizzati gli utenti e i ruoli

Figura 2: La pagina visualizza gli utenti e i ruoli (fare clic per visualizzare l'immagine a dimensione intera)

Verifica dei ruoli a cui appartiene l'utente selezionato

Quando la pagina viene caricata per la prima volta o ogni volta che il visitatore seleziona un nuovo utente dall'elenco a discesa, è necessario aggiornare le UsersRoleListcaselle di controllo delle caselle di controllo in modo che una determinata casella di controllo ruolo venga selezionata solo se l'utente selezionato appartiene a tale ruolo. A tale scopo, creare un metodo denominato CheckRolesForSelectedUser con il codice seguente:

Private Sub CheckRolesForSelectedUser() 
     ' Determine what roles the selected user belongs to 
     Dim selectedUserName As String = UserList.SelectedValue 
     Dim selectedUsersRoles() As String = Roles.GetRolesForUser(selectedUserName) 
 
     ' Loop through the Repeater's Items and check or uncheck the checkbox as needed 
     For Each ri As RepeaterItem In UsersRoleList.Items 
          ' Programmatically reference the CheckBox 
          Dim RoleCheckBox As CheckBox = CType(ri.FindControl("RoleCheckBox"), CheckBox) 
          ' See if RoleCheckBox.Text is in selectedUsersRoles 
          If Linq.Enumerable.Contains(Of String)(selectedUsersRoles, RoleCheckBox.Text) Then 
               RoleCheckBox.Checked = True 
          Else 
               RoleCheckBox.Checked = False 
          End If 
     Next 
End Sub

Il codice precedente inizia determinando chi è l'utente selezionato. Usa quindi il metodo della GetRolesForUser(userName) classe Roles per restituire il set di ruoli dell'utente specificato come matrice di stringhe. Successivamente, gli elementi del repeater vengono enumerati e viene fatto riferimento a checkBox di ogni elemento a livello di RoleCheckBox codice. CheckBox viene selezionato solo se il ruolo a cui corrisponde è contenuto all'interno della selectedUsersRoles matrice di stringhe.

Nota

La Linq.Enumerable.Contains(Of String)(...) sintassi non verrà compilata se si usa ASP.NET versione 2.0. Il Contains(Of String) metodo fa parte della libreria LINQ, che è nuova a ASP.NET 3.5. Se si usa ancora ASP.NET versione 2.0, usare invece il Array.IndexOf(Of String) metodo .

Il CheckRolesForSelectedUser metodo deve essere chiamato in due casi: quando la pagina viene prima caricata e ogni volta UserList che l'indice selezionato di DropDownList viene modificato. Pertanto, chiamare questo metodo dal Page_Load gestore eventi (dopo le chiamate a BindUsersToUserList e BindRolesToList). Creare anche un gestore eventi per l'evento SelectedIndexChanged DropDownList e chiamare questo metodo da lì.

Protected Sub Page_Load(ByVal sender As Object,ByVal e As System.EventArgs) Handles Me.Load 
     If Not Page.IsPostBack Then 
          ' Bind the users and roles 
          BindUsersToUserList() 
          BindRolesToList() 
          ' Check the selected user's roles 
          CheckRolesForSelectedUser() 
     End If 
End Sub 
 
... 
 
Protected Sub UserList_SelectedIndexChanged(ByVal sender As Object,ByVal e As System.EventArgs) Handles UserList.SelectedIndexChanged 
     CheckRolesForSelectedUser() 
End Sub

Con questo codice sul posto, è possibile testare la pagina tramite il browser. Tuttavia, poiché la UsersAndRoles.aspx pagina attualmente non ha la possibilità di assegnare utenti ai ruoli, non hanno ruoli. Verrà creata l'interfaccia per l'assegnazione degli utenti ai ruoli in un momento, in modo che sia possibile prendere la parola che il codice funziona e verificare che funzioni in un secondo momento oppure è possibile aggiungere manualmente utenti ai ruoli inserendo i record nella aspnet_UsersInRoles tabella per testare questa funzionalità ora.

Assegnazione e rimozione degli utenti dai ruoli

Quando il visitatore controlla o deseleziona un controllo CheckBox nel UsersRoleList ripetitore, è necessario aggiungere o rimuovere l'utente selezionato dal ruolo corrispondente. La proprietà CheckBox AutoPostBack è attualmente impostata su True, che causa un postback in qualsiasi momento in cui viene selezionata una casella di controllo nel ripetitore o deselezionata. In breve, è necessario creare un gestore eventi per l'evento CheckChanged CheckBox. Poiché checkBox si trova in un controllo Repeater, è necessario aggiungere manualmente l'impianto di gestione eventi. Iniziare aggiungendo il gestore eventi alla classe code-behind come Protected metodo, ad esempio:

Protected Sub RoleCheckBox_CheckChanged(ByVal sender As Object, ByVal e As EventArgs) 
 
End Sub

Verrà restituito il codice per questo gestore eventi in un momento. Ma prima di tutto si completa l'impianto di gestione degli eventi. Dalla casella di controllo all'interno del ItemTemplateripetitore aggiungere OnCheckedChanged="RoleCheckBox_CheckChanged". Questa sintassi collega il RoleCheckBox_CheckChanged gestore eventi all'evento RoleCheckBox's CheckedChanged .

<asp:CheckBox runat="server" ID="RoleCheckBox" 
     AutoPostBack="true" 
     Text='<%# Container.DataItem %>' 
     OnCheckedChanged="RoleCheckBox_CheckChanged" />

L'attività finale consiste nel completare il RoleCheckBox_CheckChanged gestore eventi. È necessario iniziare facendo riferimento al controllo CheckBox che ha generato l'evento perché questa istanza di CheckBox indica quale ruolo è stato controllato o deselezionato tramite le relative Text proprietà e Checked . Usando queste informazioni insieme a UserName dell'utente selezionato, è possibile aggiungere o rimuovere l'utente dal ruolo tramite il metodo o RemoveUserFromRolela Roles classeAddUserToRole.

Protected Sub RoleCheckBox_CheckChanged(ByVal sender As Object, ByVal e As EventArgs) 
     'Reference the CheckBox that raised this event 
     Dim RoleCheckBox As CheckBox = CType(sender, CheckBox) 
 
     ' Get the currently selected user and role 
     Dim selectedUserName As String = UserList.SelectedValue 
     Dim roleName As String = RoleCheckBox.Text 
 
     ' Determine if we need to add or remove the user from this role 
     If RoleCheckBox.Checked Then 
          ' Add the user to the role 
          Roles.AddUserToRole(selectedUserName, roleName) 
          ' Display a status message 
          ActionStatus.Text = String.Format("User {0} was added to role {1}.", selectedUserName,roleName) 
     Else 
          ' Remove the user from the role 
          Roles.RemoveUserFromRole(selectedUserName, roleName) 
          ' Display a status message 
          ActionStatus.Text = String.Format("User {0} was removed from role {1}.", selectedUserName,roleName) 
     End If 
End Sub

Il codice precedente inizia facendo riferimento a livello di codice alla Casella di controllo che ha generato l'evento, disponibile tramite il sender parametro di input. Se la casella di controllo viene selezionata, l'utente selezionato viene aggiunto al ruolo specificato, altrimenti vengono rimossi dal ruolo. In entrambi i casi, l'etichetta ActionStatus visualizza un messaggio che riepiloga l'azione appena eseguita.

Provare questa pagina tramite un browser. Selezionare l'utente Tito e quindi aggiungere Tito ai ruoli Amministratori e Supervisori.

Tito è stato aggiunto ai ruoli amministratori e supervisori

Figura 3: Tito è stato aggiunto ai ruoli amministratori e supervisori (fare clic per visualizzare l'immagine full-size)

Selezionare quindi l'utente Bruce dall'elenco a discesa. È presente un postback e i checkbox del ripetitore vengono aggiornati tramite .CheckRolesForSelectedUser Poiché Bruce non appartiene ancora a alcun ruolo, le due caselle di controllo vengono deselezionate. Aggiungere quindi Bruce al ruolo Supervisori.

Bruce è stato aggiunto al ruolo supervisori

Figura 4: Bruce è stato aggiunto al ruolo Supervisori (Fare clic per visualizzare l'immagine full-size)

Per verificare ulteriormente la funzionalità del CheckRolesForSelectedUser metodo, selezionare un utente diverso da Tito o Bruce. Si noti come le caselle di controllo vengono deselezionate automaticamente, denotando che non appartengono a alcun ruolo. Tornare a Tito. Le caselle di controllo Amministratori e Supervisori devono essere controllate.

Passaggio 2: Creazione dell'interfaccia utente "Per ruoli"

A questo punto è stata completata l'interfaccia "per utenti" e si è pronti per iniziare a affrontare l'interfaccia "per ruoli". L'interfaccia "per ruoli" richiede all'utente di selezionare un ruolo da un elenco a discesa e quindi visualizza il set di utenti che appartengono a tale ruolo in Un controllo GridView.

Aggiungere un altro controllo DropDownList all'oggetto UsersAndRoles.aspx page. Posizionare questo oggetto sotto il controllo Repeater, denominarlo RoleListe impostarne la AutoPostBack proprietà su True. Sotto, aggiungere un oggetto GridView e denominarlo RolesUserList. GridView elenca gli utenti che appartengono al ruolo selezionato. Impostare la proprietà gridView AutoGenerateColumns su False, aggiungere un ModelloField all'insieme della Columns griglia e impostare la relativa HeaderText proprietà su "Users". Definire l'oggetto TemplateField in modo che visualizzi il valore dell'espressione ItemTemplateContainer.DataItem databinding nella Text proprietà di un'etichetta denominata UserNameLabel.

Dopo aver aggiunto e configurato GridView, il markup dichiarativo dell'interfaccia "per ruolo" dovrebbe essere simile al seguente:

<h3>Manage Users By Role</h3> 
<p> 
     <b>Select a Role:</b> 
     <asp:DropDownList ID="RoleList" runat="server" AutoPostBack="true"></asp:DropDownList> 
</p> 
<p> 
     <asp:GridView ID="RolesUserList" runat="server" AutoGenerateColumns="false" 
          EmptyDataText="No users belong to this role."> 
          <Columns> 
               <asp:TemplateField HeaderText="Users"> 
                    <ItemTemplate> 
                         <asp:Label runat="server" id="UserNameLabel" 
                              Text='<%# Container.DataItem %>'></asp:Label> 
                    </ItemTemplate> 
               </asp:TemplateField> 
          </Columns> 
     </asp:GridView> 
</p>

È necessario popolare RoleList DropDownList con il set di ruoli nel sistema. A tale scopo, aggiornare il BindRolesToList metodo in modo che venga associata la matrice di stringhe restituita dal Roles.GetAllRoles metodo all'elenco RolesList a discesa (nonché il UsersRoleList ripetitore).

Private Sub BindRolesToList() 
     ' Get all of the roles 
     Dim roleNames() As String = Roles.GetAllRoles() 
     UsersRoleList.DataSource = roleNames 
     UsersRoleList.DataBind() 
 
     RoleList.DataSource = roleNames 
     RoleList.DataBind() 
End Sub

Le ultime due righe del BindRolesToList metodo sono state aggiunte per associare il set di ruoli al RoleList controllo DropDownList. La figura 5 mostra il risultato finale visualizzato tramite un browser: un elenco a discesa popolato con i ruoli del sistema.

I ruoli vengono visualizzati nell'elenco a discesa RoleList

Figura 5: i ruoli vengono visualizzati nell'elenco a discesa (fare clic per visualizzare l'immagineRoleList a dimensioni complete)

Visualizzazione degli utenti che appartengono al ruolo selezionato

Quando la pagina viene caricata per la prima volta o quando viene selezionato un nuovo ruolo da RoleList DropDownList, è necessario visualizzare l'elenco di utenti che appartengono a tale ruolo in GridView. Creare un metodo denominato DisplayUsersBelongingToRole usando il codice seguente:

Private Sub DisplayUsersBelongingToRole() 
     ' Get the selected role 
     Dim selectedRoleName As String = RoleList.SelectedValue 
 
     ' Get the list of usernames that belong to the role 
     Dim usersBelongingToRole() As String = Roles.GetUsersInRole(selectedRoleName) 
 
     ' Bind the list of users to the GridView 
     RolesUserList.DataSource = usersBelongingToRole 
     RolesUserList.DataBind() 
End Sub

Questo metodo inizia ottenendo il ruolo selezionato da RoleList DropDownList. Usa quindi il Roles.GetUsersInRole(roleName) metodo per recuperare una matrice di stringhe degli utenti appartenenti a tale ruolo. Questa matrice viene quindi associata a RolesUserList GridView.

Questo metodo deve essere chiamato in due circostanze: quando la pagina viene inizialmente caricata e quando il ruolo selezionato nell'elenco RoleList a discesa cambia. Aggiornare quindi il Page_Load gestore eventi in modo che questo metodo venga richiamato dopo la chiamata a CheckRolesForSelectedUser. Creare quindi un gestore eventi per l'evento dell'oggetto RoleListSelectedIndexChanged e chiamare anche questo metodo da lì.

Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load 
     If Not Page.IsPostBack Then 
          ' Bind the users and roles 
          BindUsersToUserList() 
          BindRolesToList() 
 
          ' Check the selected user's roles 
          CheckRolesForSelectedUser() 
 
          'Display those users belonging to the currently selected role 
          DisplayUsersBelongingToRole() 
     End If 
End Sub 
 
... 
 
Protected Sub RoleList_SelectedIndexChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles RoleList.SelectedIndexChanged 
     DisplayUsersBelongingToRole() 
End Sub

Con questo codice sul posto, RolesUserList GridView deve visualizzare gli utenti che appartengono al ruolo selezionato. Come illustrato nella figura 6, il ruolo Supervisori è costituito da due membri: Bruce e Tito.

GridView elenca gli utenti che appartengono al ruolo selezionato

Figura 6: GridView elenca gli utenti che appartengono al ruolo selezionato (fare clic per visualizzare l'immagine full-size)

Rimozione degli utenti dal ruolo selezionato

È possibile aumentare RolesUserList GridView in modo che includa una colonna di pulsanti "Remove". Facendo clic sul pulsante "Rimuovi" per un determinato utente verranno rimossi da tale ruolo.

Iniziare aggiungendo un campo pulsante Elimina a GridView. Rendere visualizzato questo campo come il file più a sinistra e modificare la relativa DeleteText proprietà da "Elimina" (impostazione predefinita) a "Rimuovi".

Screenshot che mostra come aggiungere il pulsante

Figura 7: Aggiungere il pulsante "Rimuovi" a GridView (Fare clic per visualizzare l'immagine full-size)

Quando viene fatto clic sul pulsante "Rimuovi" viene fatto clic su un postback e viene generato l'evento RowDeleting GridView. È necessario creare un gestore eventi per questo evento e scrivere codice che rimuove l'utente dal ruolo selezionato. Creare il gestore eventi e quindi aggiungere il codice seguente:

Protected Sub RolesUserList_RowDeleting(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewDeleteEventArgs) Handles RolesUserList.RowDeleting 
     ' Get the selected role 
     Dim selectedRoleName As String = RoleList.SelectedValue 
 
     ' Reference the UserNameLabel 
     Dim UserNameLabel As Label = CType(RolesUserList.Rows(e.RowIndex).FindControl("UserNameLabel"),Label) 
 
     ' Remove the user from the role 
     Roles.RemoveUserFromRole(UserNameLabel.Text, selectedRoleName) 
 
     ' Refresh the GridView 
     DisplayUsersBelongingToRole() 
 
     ' Display a status message 
     ActionStatus.Text = String.Format("User {0} was removed from role {1}.", UserNameLabel.Text,selectedRoleName) 
End Sub

Il codice inizia determinando il nome del ruolo selezionato. Fa quindi riferimento a livello di codice al UserNameLabel controllo dalla riga il cui pulsante "Rimuovi" è stato fatto clic per determinare il nome utente dell'utente da rimuovere. L'utente viene quindi rimosso dal ruolo tramite una chiamata al Roles.RemoveUserFromRole metodo . GridView RolesUserList viene quindi aggiornato e viene visualizzato un messaggio tramite il ActionStatus controllo Etichetta.

Nota

Il pulsante "Rimuovi" non richiede alcun tipo di conferma dall'utente prima di rimuovere l'utente dal ruolo. Ti invito a aggiungere un certo livello di conferma dell'utente. Uno dei modi più semplici per confermare un'azione è tramite una finestra di dialogo di conferma lato client. Per altre informazioni su questa tecnica, vedere Aggiunta di Client-Side conferma durante l'eliminazione.

La figura 8 mostra la pagina dopo che l'utente Tito è stato rimosso dal gruppo Supervisori.

Alas, Tito non è più un supervisore

Figura 8: Alas, Tito non è più un supervisore (fare clic per visualizzare l'immagine full-size)

Aggiunta di nuovi utenti al ruolo selezionato

Insieme alla rimozione degli utenti dal ruolo selezionato, anche il visitatore di questa pagina deve essere in grado di aggiungere un utente al ruolo selezionato. L'interfaccia migliore per l'aggiunta di un utente al ruolo selezionato dipende dal numero di account utente che si prevede di avere. Se il tuo sito Web ospita solo poche decine di account utente o meno, puoi usare un elenco a discesa qui. Se potrebbero esserci migliaia di account utente, si vuole includere un'interfaccia utente che consente al visitatore di paginare gli account, cercare un account specifico o filtrare gli account utente in qualche altro modo.

Per questa pagina viene usata un'interfaccia molto semplice che funziona indipendentemente dal numero di account utente nel sistema. In nome, useremo un controllo TextBox, richiedendo al visitatore di digitare il nome utente dell'utente che vuole aggiungere al ruolo selezionato. Se non esiste alcun utente con tale nome o se l'utente è già membro del ruolo, verrà visualizzato un messaggio in ActionStatus Etichetta. Tuttavia, se l'utente esiste e non è un membro del ruolo, verranno aggiunti al ruolo e aggiornando la griglia.

Aggiungere una casella di testo e un pulsante sotto GridView. Impostare il controllo TextBox IDUserNameToAddToRole su e impostare rispettivamente le proprietà e Text il pulsante ID su AddUserToRoleButton e "Aggiungi utente al ruolo".

<p> 
     <b>UserName:</b> 
     <asp:TextBox ID="UserNameToAddToRole" runat="server"></asp:TextBox> 
     <br /> 
     <asp:Button ID="AddUserToRoleButton" runat="server" Text="Add User to Role" /> 
</p>

Creare quindi un Click gestore eventi per AddUserToRoleButton e aggiungere il codice seguente:

Protected Sub AddUserToRoleButton_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles AddUserToRoleButton.Click 
     ' Get the selected role and username 
     Dim selectedRoleName As String = RoleList.SelectedValue 
     Dim userToAddToRole As String = UserNameToAddToRole.Text 
 
     ' Make sure that a value was entered 
     If userToAddToRole.Trim().Length = 0 Then 
          ActionStatus.Text = "You must enter a username in the textbox." 
          Exit Sub 
     End If 
 
     ' Make sure that the user exists in the system 
     Dim userInfo As MembershipUser = Membership.GetUser(userToAddToRole) 
     If userInfo Is Nothing Then 
          ActionStatus.Text = String.Format("The user {0} does not exist in the system.",userNameToAddToRole) 
          Exit Sub 
     End If 
 
     ' Make sure that the user doesn't already belong to this role 
     If Roles.IsUserInRole(userToAddToRole, selectedRoleName) Then 
          ActionStatus.Text = String.Format("User {0} already is a member of role {1}.", UserNameToAddToRole,selectedRoleName) 
          Exit Sub 
     End If 
 
     ' If we reach here, we need to add the user to the role 
     Roles.AddUserToRole(userToAddToRole, selectedRoleName) 
 
     ' Clear out the TextBox 
     userNameToAddToRole.Text = String.Empty 
 
     ' Refresh the GridView 
     DisplayUsersBelongingToRole() 
 
     ' Display a status message 
     ActionStatus.Text = String.Format("User {0} was added to role {1}.", UserNameToAddToRole,selectedRoleName) 
End Sub

La maggior parte del codice nel Click gestore eventi esegue vari controlli di convalida. Garantisce che il visitatore abbia fornito un nome utente nella UserNameToAddToRole Casella di testo, che l'utente esista nel sistema e che non appartengano già al ruolo selezionato. Se uno di questi controlli ha esito negativo, viene visualizzato un messaggio appropriato in ActionStatus e il gestore eventi viene chiuso. Se tutti i controlli passano, l'utente viene aggiunto al ruolo tramite il Roles.AddUserToRole metodo . In seguito, la proprietà TextBox viene cancellata, GridView viene aggiornata e l'etichetta TextActionStatus visualizza un messaggio che indica che l'utente specificato è stato aggiunto correttamente al ruolo selezionato.

Nota

Per assicurarsi che l'utente specificato non appartenga già al ruolo selezionato, viene usato il Roles.IsUserInRole(userName, roleName) metodo, che restituisce un valore booleano che indica se userName è un membro di roleName. Questo metodo verrà usato di nuovo nell'esercitazione successiva quando si esamina l'autorizzazione basata su ruoli.

Visitare la pagina tramite un browser e selezionare il ruolo Supervisori dall'elenco RoleList a discesa. Provare a immettere un nome utente non valido: verrà visualizzato un messaggio che spiega che l'utente non esiste nel sistema.

Non è possibile aggiungere un utente non esistente a un ruolo

Figura 9: Non è possibile aggiungere un utente non esistente a un ruolo (fare clic per visualizzare l'immagine full-size)

Provare ora ad aggiungere un utente valido. Andare avanti e riaggiungere Tito al ruolo Supervisori.

Tito è ancora una volta un supervisore!

Figura 10: Tito è ancora una volta un supervisore! (Fare clic per visualizzare l'immagine full-size)

Passaggio 3: Aggiornamento incrociato delle interfacce "Per utente" e "Per ruolo"

La UsersAndRoles.aspx pagina offre due interfacce distinte per la gestione di utenti e ruoli. Attualmente, queste due interfacce agiscono in modo indipendente tra loro in modo che sia possibile che una modifica apportata in un'interfaccia non venga riflessa immediatamente nell'altra. Si supponga, ad esempio, che il visitatore della pagina selezioni il ruolo Supervisori dall'elenco RoleList DropDownList, che elenca Bruce e Tito come membri. Successivamente, il visitatore seleziona Tito dall'elenco UserList a discesa, che controlla le caselle di controllo Amministratori e supervisori nel UsersRoleList ripetitore. Se il visitatore deseleziona quindi il ruolo supervisore dal ripetitore, Tito viene rimosso dal ruolo Supervisori, ma questa modifica non viene riflessa nell'interfaccia "per ruolo". GridView mostrerà comunque Tito come membro del ruolo Supervisori.

Per correggere questo problema, è necessario aggiornare GridView ogni volta che un ruolo viene controllato o deselezionato dal UsersRoleList ripetitore. Analogamente, è necessario aggiornare il ripetitore ogni volta che un utente viene rimosso o aggiunto a un ruolo dall'interfaccia "per ruolo".

Il ripetitore nell'interfaccia "by user" viene aggiornato chiamando il CheckRolesForSelectedUser metodo . L'interfaccia "per ruolo" può essere modificata nel RolesUserList gestore eventi di RowDeleting GridView e nel AddUserToRoleButton gestore eventi button Click . Pertanto, è necessario chiamare il CheckRolesForSelectedUser metodo da ognuno di questi metodi.

Protected Sub RolesUserList_RowDeleting(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewDeleteEventArgs) Handles RolesUserList.RowDeleting 
     ... Code removed for brevity ... 
 
     ' Refresh the "by user" interface 
     CheckRolesForSelectedUser() 
End Sub 
 
Protected Sub AddUserToRoleButton_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles AddUserToRoleButton.Click 
     ... Code removed for brevity ... 
 
     ' Refresh the "by user" interface 
     CheckRolesForSelectedUser() 
End Sub

Analogamente, l'interfaccia GridView nell'interfaccia "per ruolo" viene aggiornata chiamando il metodo e l'interfaccia DisplayUsersBelongingToRole "by user" viene modificata tramite il RoleCheckBox_CheckChanged gestore eventi. Pertanto, è necessario chiamare il DisplayUsersBelongingToRole metodo da questo gestore eventi.

Protected Sub RoleCheckBox_CheckChanged(ByVal sender As Object, ByVal e As EventArgs) 
     ... Code removed for brevity ... 
 
     ' Refresh the "by role" interface 
     DisplayUsersBelongingToRole() 
End Sub

Con queste modifiche al codice secondario, le interfacce "per utente" e "per ruolo" ora vengono aggiornate correttamente. Per verificare questo problema, visitare la pagina tramite un browser e selezionare Rispettivamente Tito e Supervisori da UserList e RoleList DropDownLists. Si noti che quando si deseleziona il ruolo Supervisori per Tito dall'interfaccia "by user", Tito viene rimosso automaticamente dall'interfaccia "per ruolo". L'aggiunta di Tito al ruolo Supervisori dall'interfaccia "per ruolo" controlla automaticamente la casella di controllo Supervisori nell'interfaccia "by user".

Passaggio 4: Personalizzazione di CreateUserWizard per includere un passaggio "Specifica ruoli"

Nell'esercitazione Creazione di account utente è stato illustrato come usare il controllo Web CreateUserWizard per fornire un'interfaccia per la creazione di un nuovo account utente. Il controllo CreateUserWizard può essere usato in uno dei due modi seguenti:

  • Come mezzo per i visitatori di creare un proprio account utente nel sito e
  • Come mezzo per gli amministratori di creare nuovi account

Nel primo caso d'uso, un visitatore arriva al sito e compila CreateUserWizard, immettendo le informazioni necessarie per la registrazione nel sito. Nel secondo caso, un amministratore crea un nuovo account per un'altra persona.

Quando un account viene creato da un amministratore per un'altra persona, potrebbe essere utile consentire all'amministratore di specificare i ruoli a cui appartiene il nuovo account utente. Nell'esercitazione Archiviazionedi informazioni utente aggiuntive è stato illustrato come personalizzare CreateUserWizard aggiungendo altri WizardSteps. Verrà illustrato come aggiungere un passaggio aggiuntivo a CreateUserWizard per specificare i ruoli del nuovo utente.

Aprire la CreateUserWizardWithRoles.aspx pagina e aggiungere un controllo CreateUserWizard denominato RegisterUserWithRoles. Impostare la proprietà del ContinueDestinationPageUrl controllo su "~/Default.aspx". Poiché l'idea è che un amministratore usa questo controllo CreateUserWizard per creare nuovi account utente, impostare la proprietà del LoginCreatedUser controllo su False. Questa LoginCreatedUser proprietà specifica se il visitatore viene eseguito automaticamente l'accesso come utente appena creato e il valore predefinito è True. È stato impostato su False perché quando un amministratore crea un nuovo account che si vuole mantenere connesso come se stesso.

Selezionare quindi "Aggiungi/Rimuovi WizardSteps..." opzione dallo Smart Tag CreateUserWizard e aggiungere un nuovo WizardStepoggetto , impostandone su IDSpecifyRolesStep. Spostare l'oggetto SpecifyRolesStep WizardStep in modo che venga eseguito dopo il passaggio "Iscrizione per il nuovo account", ma prima del passaggio "Completa". Impostare la WizardStepproprietà su Title "Specifica ruoli", sulla StepType relativa proprietà su Stepe sulla relativa AllowReturn proprietà su False.

Screenshot che mostra le proprietà Specifica ruoli selezionate nella finestra Editor raccolta passaggi guidata.

Figura 11: Aggiungere il valore "Specifica ruoli" WizardStep al CreateUserWizard (Fare clic per visualizzare l'immagine full-size)

Dopo questa modifica il markup dichiarativo di CreateUserWizard dovrebbe essere simile al seguente:

<asp:CreateUserWizard ID="RegisterUserWithRoles" runat="server" 
     ContinueDestinationPageUrl="~/Default.aspx" LoginCreatedUser="False"> 
     <WizardSteps> 
          <asp:CreateUserWizardStep ID="CreateUserWizardStep1" runat="server"> 
          </asp:CreateUserWizardStep> 
          <asp:WizardStep ID="SpecifyRolesStep" runat="server" StepType="Step" 
               Title="Specify Roles" AllowReturn="False"> 
          </asp:WizardStep> 
          <asp:CompleteWizardStep ID="CompleteWizardStep1" runat="server"> 
          </asp:CompleteWizardStep> 
     </WizardSteps> 
</asp:CreateUserWizard>

Nella sezione "Specifica ruoli" WizardStepaggiungere un controllo CheckBoxList denominato RoleList. This CheckBoxList elenca i ruoli disponibili, consentendo alla persona che visita la pagina di controllare i ruoli a cui appartiene l'utente appena creato.

Sono state lasciate due attività di codifica: prima è necessario popolare RoleList CheckBoxList con i ruoli nel sistema. In secondo luogo, è necessario aggiungere l'utente creato ai ruoli selezionati quando l'utente passa dal passaggio "Specifica ruoli" al passaggio "Completa". È possibile eseguire la prima attività nel Page_Load gestore eventi. Il codice seguente fa riferimento a RoleList CheckBox nella prima visita alla pagina e associa i ruoli nel sistema.

Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load 
     If Not Page.IsPostBack Then 
          ' Reference the SpecifyRolesStep WizardStep 
          Dim SpecifyRolesStep As WizardStep = CType(RegisterUserWithRoles.FindControl("SpecifyRolesStep"),WizardStep) 
 
          ' Reference the RoleList CheckBoxList 
          Dim RoleList As CheckBoxList = CType(SpecifyRolesStep.FindControl("RoleList"), CheckBoxList) 
 
          ' Bind the set of roles to RoleList 
          RoleList.DataSource = Roles.GetAllRoles() 
          RoleList.DataBind() 
     End If 
End Sub

Il codice precedente dovrebbe essere familiare. Nell'esercitazione Archiviazionedi informazioni utente aggiuntive sono stati usati due FindControl istruzioni per fare riferimento a un controllo Web dall'interno di un oggetto personalizzato WizardStep. Il codice che associa i ruoli a CheckBoxList è stato ottenuto in precedenza in questa esercitazione.

Per eseguire la seconda attività di programmazione è necessario conoscere quando è stato completato il passaggio "Specifica ruoli". Si ricordi che CreateUserWizard ha un ActiveStepChanged evento, che viene generato ogni volta che il visitatore passa da un passaggio a un altro. In questo caso è possibile determinare se l'utente ha raggiunto il passaggio "Completa". in tal caso, è necessario aggiungere l'utente ai ruoli selezionati.

Creare un gestore eventi per l'evento ActiveStepChanged e aggiungere il codice seguente:

Protected Sub RegisterUserWithRoles_ActiveStepChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles RegisterUserWithRoles.ActiveStepChanged 
     'Have we JUST reached the Complete step? 
     If RegisterUserWithRoles.ActiveStep.Title = "Complete" Then 
          ' Reference the SpecifyRolesStep WizardStep 
          Dim SpecifyRolesStep As WizardStep = CType(RegisterUserWithRoles.FindControl("SpecifyRolesStep"),WizardStep) 
 
          ' Reference the RoleList CheckBoxList 
          Dim RoleList As CheckBoxList = CType(SpecifyRolesStep.FindControl("RoleList"), CheckBoxList) 
 
          ' Add the checked roles to the just-added user 
          For Each li As ListItem In RoleList.Items 
               If li.Selected Then 
                    Roles.AddUserToRole(RegisterUserWithRoles.UserName, li.Text) 
               End If 
          Next 
     End If 
End Sub

Se l'utente ha appena raggiunto il passaggio "Completato", il gestore eventi enumera gli elementi di RoleList CheckBoxList e l'utente appena creato viene assegnato ai ruoli selezionati.

Visitare questa pagina tramite un browser. Il primo passaggio in CreateUserWizard è il passaggio standard "Iscrizione per il nuovo account", che richiede il nome utente, la password, la password, la posta elettronica e altre informazioni chiave del nuovo utente. Immettere le informazioni per creare un nuovo utente denominato Wanda.

Creare un nuovo utente denominato Wanda

Figura 12: Creare un nuovo utente denominato Wanda (fare clic per visualizzare l'immagine a dimensioni complete)

Fare clic sul pulsante "Crea utente". CreateUserWizard chiama internamente il metodo, creando il Membership.CreateUser nuovo account utente e quindi passa al passaggio successivo "Specifica ruoli". Di seguito sono elencati i ruoli di sistema. Selezionare la casella di controllo Supervisori e fare clic su Avanti.

Rendere Wanda un membro del ruolo supervisori

Figura 13: Make Wanda a Member of the Supervisors Role (Fare clic per visualizzare l'immagine full-size)

Facendo clic su Avanti viene generato un postback e viene aggiornato il ActiveStep passaggio "Completa". Nel gestore eventi l'account ActiveStepChanged utente creato di recente viene assegnato al ruolo Supervisori. Per verificare questa operazione, tornare alla pagina e selezionare Supervisori dall'elenco UsersAndRoles.aspxRoleList a discesa. Come illustrato nella figura 14, i supervisori sono ora costituiti da tre utenti: Bruce, Tito e Wanda.

Bruce, Tito e Wanda sono Tutti i supervisori

Figura 14: Bruce, Tito e Wanda sono Tutti i supervisori (Fare clic per visualizzare l'immagine full-size)

Riepilogo

Il framework Ruoli offre metodi per recuperare informazioni sui ruoli e sui metodi di un determinato utente per determinare quali utenti appartengono a un ruolo specificato. Esistono inoltre diversi metodi per aggiungere e rimuovere uno o più utenti in uno o più ruoli. In questa esercitazione sono stati illustrati solo due di questi metodi: AddUserToRole e RemoveUserFromRole. Esistono varianti aggiuntive progettate per aggiungere più utenti a un singolo ruolo e assegnare più ruoli a un singolo utente.

Questa esercitazione include anche un'occhiata all'estensione del controllo CreateUserWizard per includere un WizardStep oggetto per specificare i ruoli dell'utente appena creati. Questo passaggio potrebbe aiutare un amministratore a semplificare il processo di creazione di account utente per nuovi utenti.

A questo punto è stato illustrato come creare ed eliminare ruoli e come aggiungere e rimuovere gli utenti dai ruoli. Tuttavia, è ancora necessario esaminare l'applicazione dell'autorizzazione basata sul ruolo. Nell'esercitazione seguente si esaminerà la definizione delle regole di autorizzazione dell'URL in base al ruolo, nonché come limitare le funzionalità a livello di pagina in base ai ruoli dell'utente attualmente registrati.

Programmazione felice!

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, allenatore 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 speciali a...

Questa serie di esercitazioni è stata esaminata da molti revisori utili. Il revisore principale per questa esercitazione era Teresa Murphy. Interessati a esaminare i prossimi articoli MSDN? In tal caso, lasciami una riga in mitchell@4GuysFromRolla.com