Welcome to AspAdvice Sign in | Join | Help

.Net Discoveries

An attempt to pass along some answers I have discovered in my .Net coding.
A Better ASP.Net Member/Role Management Page Pt. 9

Prologue

**Author Note – If you are bewildered by a line (perhaps two) that are red and bold, they are errors or corrections/additions. Please see the comments, after the article for information regarding the highlighted line(s).**

It's kind of funny how once you really get into using things that you find little (or not so little) improvements that can make code you previously did that much more effective and useful in your (and probably other) environments. This is the case with the ‘Better ASP.Net Member/Role Management Page’.

If you aren’t familiar with this series here’s the rundown. If you want to follow along with the other posts, you can create the management page yourself by reviewing all the posts for part 1, part 2, part 3, part 4, part 5, part 6, part 7 and part 8. Welcome to part 9.

Problem

In the process of creating a site here at work, I have been developing a user registration process for the site. One of the steps of the registration process is allowing the user to sign up for email notifications in different areas. The record of their selections is stored in a table that will be polled for recipients when a notification should be sent. It suddenly dawned on me that if a user signs up for notifications and later the administrator deletes the user, that the user’s notifications will not be removed (since our management control doesn’t have code to purge the notifications table). To solve this, I could put extra code into the UserControl to remove the notifications, but this is a poor solution because I may need to add further code in the future and breaks the usability of our control. This also brings up other points such as what if the administrator changes the user’s email or deactivates the user, then I may also need to modify the notifications list.

Suddenly the light bulb comes on and I realize that we never included any events in our control. For the control to be self-contained, we need to raise events so that we can code against specific events that take place in the control, such as when a user is created, deleted or changed (and the same goes for roles), without having to modify it’s code. This post is intended to add several events so that we can code against these events in our containing page.

Solution

First, let’s define the events that can happen and that we’ll be adding (I’m choosing to add all of them that I think could possibly someday be relevant to somebody). I won’t be using most of them, probably ever, but who knows. The list I made fell into 3 categories of events as shown in the table below. I chose the 3 categories mainly due to the EventArgs that we’ll be developing to pass with our events. These three categories will fit our EventArgs more nicely if divided as follows:

User Events

Role Events

Role/User Events

Added Added User Un/Assigned to Role
Deleted Deleted User Un/Assigning to a Role
Changed Sec. Question Changed  
Changed Sec. Answer    
Reset Password    
Changed Username    
Changed Email    
Activated    
Deactivated    
UserDeleting    

As I mentioned above, we’ll be creating EventArgs specifically for each of these types of events. Perhaps I’ll back up a little… When creating an event in our control, we can really define it any way we would like to (the parameters that it will pass are up to us to define in anyway we want). That being said though, best practice is to follow Microsoft’s pattern for creating events:

Public Event WhatHappened(ByVal sender As Object, ByVal e As EventArgs)

The thing we’ll notice though is that EventArgs is REALLY generic. There isn’t much there to work with (no properties etc.), so we’ll define or own custom EventArgs that inherit from the EventArgs class. This way we can tailor it to our needs. (Check your event handlers and you’ll see that many of the built in events do this). So, let’s start by making some different classes of EventArgs. First, we’ll create an EventArgs for the majority of our user events. I’ll be adding these class definitions after our UserControl’s class ends. Add the following:

Public Class UserEventArgs
    Inherits EventArgs

    Public Enum UserEventAction
        NotSet
        UserDeleted
        UserDeleting
        UserAdded
        ChangeSecurityQuestion
        ChangeSecurityAnswer 
        UserDeactivated
        UesrActivated
        PasswordChanged
        PasswordReset 
    End Enum 

   Public Sub New() 

   End Sub 

    Public Sub New(ByVal action As UserEventAction, _
                           ByVal ActionArgument As String)
        _Action = action
        _ActionArgument = ActionArgument
    End Sub 

    Private _ActionArgument As String = ""
    Public Property ActionArgument() As String
        Get
            Return _ActionArgument
        End Get
        Set(ByVal value As String)
            _ActionArgument = value
        End Set
    End Property 

    Private _Action As UserEventAction = UserEventAction.NotSet
    Public Property Action() As UserEventAction
        Get
            Return _Action
        End Get
        Set(ByVal value As UserEventAction)
            _Action = value
        End Set
    End Property
End Class

Our EventArgs for the user events will allow us to send information to the developer regarding our event, specifically, what action happened and then we’ll pass the username as the action argument. Some of the user events will require more than one argument to be passed, such as when the username is changed, we’ll need to pass both the old and new usernames. We’ll create a new EventArgs class(es) for these. Additionally, they may not need an action parameter because we already know what the action is by virtue that it is being called. Add the following to your project:

Public Class UsernameChangedEventArgs
    Inherits EventArgs 

    Public Sub New() 

    End Sub 

    Public Sub New(ByVal oldUsername As String, _
                           ByVal newUsername As String)
        _oldUsername = oldUsername
        _newUsername = newUsername
    End Sub 

    Private _oldUsername As String
    Public Property OldUsername() As String
        Get
            Return _oldUsername
        End Get
        Set(ByVal value As String)
            _oldUsername = value
        End Set
    End Property 

    Private _newUsername As String
    Public Property NewUsername() As String
        Get
            Return _newUsername
        End Get
        Set(ByVal value As String)
            _newUsername = value
        End Set
    End Property
End Class

We’ll also need to pass two parameters for email, the old and new email addresses so it will get its own class as well, very similar on the UsernameChangedEventArgs:

Public Class EmailChangedEventArgs
    Inherits EventArgs 

    Public Sub New() 

    End Sub 

    Public Sub New(ByVal oldEmail As String, ByVal newEmail As String)
        _oldEmail = oldEmail
        _newEmail = newEmail
    End Sub 

    Private _oldEmail As String
    Public Property OldEmail() As String
        Get
            Return _oldEmail
        End Get
        Set(ByVal value As String)
            _oldEmail = value
        End Set
    End Property 

    Private _newEmail As String
    Public Property NewEmail() As String
        Get
            Return _newEmail
        End Get
        Set(ByVal value As String)
            _newEmail = value
        End Set
    End Property
End Class

Next we’ll add the EventArg class for RoleEventArgs:

Public Class RoleEventArgs
    Inherits EventArgs 

    Public Enum RoleEventActions
        NotSet
        Deleted
        Added
        Changed
    End Enum 

    Public Sub New() 

    End Sub 

    Public Sub New(ByVal action As RoleEventActions, _
                            ByVal ActionArgument As String)
        _Action = action
        _ActionArgument = ActionArgument
    End Sub  

    Private _ActionArgument As String = ""
    Public Property ActionArgument() As String
        Get
            Return _ActionArgument
        End Get
        Set(ByVal value As String)
            _ActionArgument = value
        End Set
    End Property 

    Private _Action As RoleEventActions = RoleEventActions.NotSet
    Public Property Action() As RoleEventActions
        Get
            Return _Action
        End Get
        Set(ByVal value As RoleEventActions)
            _Action = value
        End Set
    End Property
End Class

Our role changed event will need to return more information than just one string as it passes old AND new information, so it has a class as the argument. This argument class is defined within the EventArgs class itself. Add the following:

Public Class RoleChangedEventArgs
    Inherits EventArgs 

    Public Enum RoleChangedEventActions
        NotSet
        Renamed
        DescriptionChanged
    End Enum 

    Public Sub New() 

    End Sub 

    Public Sub New(ByVal action As RoleChangedEventActions, _
                           ByVal ActionArguments As RoleChangedEventActionArgs)
        _Action = action
        _ActionArgument = ActionArguements   
    End Sub 

    Private _ActionArgument As RoleChangedEventActionArgs = Nothing
    Public Property ActionArgument() As RoleChangedEventActionArgs
        Get
            Return _ActionArgument
        End Get
        Set(ByVal value As RoleChangedEventActionArgs)
            _ActionArgument = value
        End Set
    End Property 

    Private _Action As RoleChangedEventActions = _
                                            RoleChangedEventActions.NotSet
    Public Property Action() As RoleChangedEventActions
        Get
            Return _Action
        End Get
        Set(ByVal value As RoleChangedEventActions)
            _Action = value
        End Set
    End Property 

    Public Class RoleChangedEventActionArgs
        Public Sub New() 

        End Sub

        Public Sub New(ByVal oldRoleName As String, _
                               ByVal newRoleName As String, _
                               ByVal oldDescription As String, _
                               ByVal newDescription As String)
            _oldRoleName = oldRoleName
            _newRoleName = newRoleName
            _oldDescription = oldDescription
            _newDescription = newDescription
        End Sub

        Private _oldRoleName As String = ""
        Public Property OldRoleName As String
            Get
                Return _oldRoleName
            End Get
            Set(ByVal value As String)
                _oldRoleName = value
            End Set
        End Property

        Private _newRoleName As String = ""
        Public Property NewRoleName As String
            Get
                Return _newRoleName
            End Get
            Set(ByVal value As String)
                _newRoleName = value
            End Set
        End Property

        Private _oldDescription As String = ""
        Public Property OldDescription As String
            Get
                Return _oldDescription
            End Get
            Set(ByVal value As String)
                _oldDescription = value
            End Set
        End Property

        Private _newDescription As String = ""
        Public Property NewDescription As String
            Get
                Return _newDescription
            End Get
            Set(ByVal value As String)
                _newDescription = value
            End Set
        End Property
    End Class
End Class

Our final class will be our UserRoleAssignement arguments. These will pass arrays of strings for the roles that the user was added/removed from. Add the following class to our project:

Public Class RoleUserAssignmentArgs
    Inherits EventArgs 

    Public Sub New() 

    End Sub 

    Public Sub New(ByVal addedroles As String(), _
                           ByVal removedRoles As String(), _
                           ByVal username As String)
        _AddedRoles = addedroles
        _RemovedRoles = removedRoles
        _Username = username
    End Sub

    Private _RemovedRoles As String()
    Public Property RemovedRoles() As String()
        Get
            Return _RemovedRoles
        End Get
        Set(ByVal value As String())
            _RemovedRoles = value
        End Set
    End Property

    Private _AddedRoles As String()
    Public Property AddedRoles() As String()
        Get
            Return _AddedRoles
        End Get
        Set(ByVal value As String())
            _AddedRoles = value
        End Set
    End Property

    Private _Username As String = ""
    Public Property Username() As String
        Get
            Return _Username
        End Get
        Set(ByVal value As String)
            _Username = value
        End Set
    End Property
End Class

The following class was added later to facilitate the RoleUserAssignmentChanging event discussed in the comments (please see them for more details):

Public Class RoleUserAssignmentChangingArgs
    Inherits EventArgs 

    Public Sub New() 

    End Sub 

    Public Sub New(ByVal addedroles As String(), _
             ByVal removedRoles As String(), ByVal username As String)
        _AddedRoles = addedroles
        _RemovedRoles = removedRoles
        _Username = username
    End Sub
    Private _RemovedRoles As String()
    Public Property RemovedRoles() As String()
        Get
            Return _RemovedRoles
        End Get
        Set(ByVal value As String())
            _RemovedRoles = value
        End Set
    End Property
    Private _AddedRoles As String()
    Public Property AddedRoles() As String()
        Get
            Return _AddedRoles
        End Get
        Set(ByVal value As String())
            _AddedRoles = value
        End Set
    End Property
    Private _Username As String = ""
    Public Property Username() As String
        Get
            Return _Username
        End Get
        Set(ByVal value As String)
            _Username = value
        End Set
    End Property
    Private _Cancel As Boolean = False
    Public Property Cancel() As Boolean
        Get
            Return _Cancel
        End Get
        Set(ByVal value As Boolean)
            _Cancel = value
        End Set
    End Property
End Class

(As an afterthought I added constructors to all the classes so that it would be easy to create a new instance and pass it as a parameter when the event is raised, rather than creating, populating and then passing argument whenever an event is raised – we can do it all in one line rather than several in many cases).

Next, we’ll need to create the event definitions for each of our events. These I will put at the top of our control’s code, with the constants and other definitions. Add the following event definitions:

Public Event UserDeleting(ByVal sender As Object, _
                                           ByVal e As UserEventArgs)

Public Event UserDeleted(ByVal sender As Object, ByVal e As UserEventArgs)
Public Event UserAdded(ByVal sender As Object, ByVal e As UserEventArgs)
Public Event UserChangedSecurityQuestion(ByVal sender As Object, _
                                                              ByVal e As UserEventArgs)
Public Event UserChangedSecurityAnswer(ByVal sender As Object, _
                                                             ByVal e As UserEventArgs)
Public Event UserChangedUsername(ByVal sender As Object, _
                                   ByVal e As Public Class UsernameChangedEventArgs)
Public Event UserDeactivated(ByVal sender As Object, _
                                           ByVal e As UserEventArgs)
Public Event UserActivated(ByVal sender As Object, _
                                       ByVal e As UserEventArgs)
Public Event UserPasswordReset(ByVal sender As Object, _
                                                ByVal e As UserEventArgs)
Public Event UserPasswordChanged(ByVal sender As Object, _
                                                    ByVal e As UserEventArgs)
Public Event UserEmailChanged(ByVal sender As Object, _
                                              ByVal e As EmailChangedEventArgs)

Public Event RoleAdded(ByVal sender As Object, ByVal e As RoleEventArgs)
Public Event RoleDeleted(ByVal sender As Object, ByVal e As RoleEventArgs)
Public Event RoleChanged(ByVal sender As Object, _
                                      ByVal e As RoleChangedEventArgs)

Public Event UserRoleAssignmentChanged(ByVal sender As Object, _
                                                          ByVal e As RoleUserAssignmentArgs)
Public Event UserRoleAssignmentChanging( _
          ByVal sender As Object, _
          ByVal e As RoleUserAssignmentChangingArgs)

We create nine events for things we could do with user accounts, notice that for most, the parameters are the same, they use UserEventArgs as the second parameter (only the Usernamechanged and UserEmailChanged use different ones). Next we add three events for Roles. Again, notice that all the parameters are the same (except RoleChanged), and that we’re using our RoleEventArgs class. Finally, we create our User/Role assignment event, and use our RoleUserAssignmetArgs class.

Now, all we need to do is raise these events at the proper time so that someone using our control can handle the events. We’ll work our way down the list of events we just created, starting with UserDeleting. We’ll add this to our btnDeleteUserYes_Click event handler in our UserControl. Add the following BEFORE our Membership.DeleteUser line:

RaiseEvent UserDeleting(Me, New UserEventArgs _ 
                             (UserEventArgs.UserEventAction.UserDeleting, _
                                          lblDeleteConfirmUserName.Text))

Then, add the following line directly AFTER the Membership.DeleteUser line:

RaiseEvent UserDeleted(Me, New UserEventArgs _
                                        (UserEventArgs.UserEventAction.UserDeleted, _
                                          lblDeleteConfirmUserName.Text))

Here we raise the event that the user was deleted, we add the current element as the sender (me), and then attach event args stating that we deleted the user and passing the username.

Next we’ll call our UserAdded event. Add it to the cuwAddUser_CreatedUser event handler, directly after the UpdateRoleMembership line:

RaiseEvent UserAdded(Me, New UserEventArgs _
                                             (UserEventArgs.UserEventAction.UserAdded, _
                                              cuwTheUser.UserName))

Now, we’ll raise the ChangedSecurityQuestion and ChangeSecurityAnswer events, they’ll go right next to each other and we’ll add these to the lnkChangeSecurityQASave_Click event handler:

RaiseEvent UserChangedSecurityQuestion(Me, New UserEventArgs _ 
                        (UserEventArgs.UserEventAction.ChangeSecurityQuestion,  _
                         lblUsernameEdit.Text))

RaiseEvent UserChangedSecurityAnswer(Me, New UserEventArgs _
                           (UserEventArgs.UserEventAction.ChangeSecurityAnswer, _
                            lblUsernameEdit.Text))

The UserChangedUsername event will be raised in the lnkChangeUsernameSave_Click event handler. Add it as the first line in the ChangeUserName if/then statement as follows:

RaiseEvent UserChangedUsername(Me, New UsernameChangedEventArgs _
                                      (lblCurrentUsername.Text, txtNewUsername.Text))

The UserDeactivated and UserActivated events will both reside in the ChangeUserIsApproved subroutine. We’ll need an if then statement to check if the user was activated, or deactivated and raise our events that way. Add this code after the membership.UpdateUser line (the last line):

If theCheckbox.Checked Then
   RaiseEvent UserActivated(Me, New UserEventArgs _
                        (UserEventArgs.UserEventAction.UesrActivated, sUserName))
Else
   RaiseEvent UserDeactivated(Me, New UserEventArgs _
                    (UserEventArgs.UserEventAction.UserDeactivated, sUserName))
End If

The PasswordReset event will be added to the btnResetPasswordYes_Click event handler, put it directly after the Membership.GetUser().ResetPassword() line as follows:

RaiseEvent UserPasswordReset(Me, New UserEventArgs _
        (UserEventArgs.UserEventAction.PaswordReset, lblUsernameEdit.Text))

The PasswordChanged event will be added to the lnkChangePasswordSave_Click event handler, add it directly below the mu.ChangePassword line as follows:

RaiseEvent UserPasswordChanged(sender, New UserEventArgs _
                                 (UserEventArgs.UserEventAction.PasswordChanged, _
                                   lblUsernameEdit.Text))

And finally, the EmailChanged event will be added to the lnkEditUserSave_Click, we need to add the following two lines so that we can tell if the email has been changed. Add them right after the Dim theEditedUser as MemberhipUser line:

Dim bChangedEmail As Boolean = If(theEditedUser.Email _
                                                      = txtEmail.Text, False, True)
Dim oldEmail As String = theEditedUser.Email

Then, we’ll add our RaiseEvent line right after the Membership.UpdateUser line, right before the UpdateRoleMembership line:

If bChangedEmail Then
   RaiseEvent UserEmailChanged(Me, _
                    New EmailChangedEventArgs(oldEmail, txtEmail.Text))
End If

Notice that calling it is conditional on the password being different (we check this earlier in our code).

Now, let’s concentrate on the role events. We’ll start with RoleDeleted. We’ll add this to the btnDeleteRoleYes_Click event handler. Add it directly after the Roles.DeleteRole line as follows:

RaiseEvent RoleDeleted(Me, New RoleEventArgs _
                  (RoleEventArgs.RoleEventActions.Deleted, lblRoleToDelete.Text))

Next, we’ll do the RoleAdded event. We’ll add it to the btnAddRole_Click event handler. Add it directly after the Roles.CreateRole line as follows:

RaiseEvent RoleAdded(Me, New RoleEventArgs _
                 (RoleEventArgs.RoleEventActions.Added, txtNewRoleName .Text))

Finally, we’ll add the RoleChanged event. There are a couple different times that we can raise this event that we’ll have manage. We can rename the role, or we can change the description. Due to this, we’ll use the RoleChangedEventArgs class for EventArgs so we can pass old and new data as we’ll as role name when it is the description that changes.

We’ll start with renaming the role. We’ll raise our event in the btnRoleRenameYes_Click event handler. Raise our event directly after the Role.DeleteRole() line as follows:

RaiseEvent RoleChanged(Me, New RoleChangedEventArgs _
         (RoleChangedEventArgs.RoleChangedEventActions.Renamed, _
          New RoleChangedEventArgs.RoleChangedEventActionArgs _
          (lblRoleToRename.Text, txtNewEditRoleName.Text, "", "")))

We’ll have to do a little work before we can raise our event for role description changed. We currently don’t keep our old role name so we’ll need to add a label to our HMTL code to store this. In the code for our Change Role Description Dialog, add the following line below the instructions line:

<asp:Label ID="lblOldRoleDescription" runat="server" Visible="false" />

Next, we’ll populate this label with our old name, to do this we’ll add a line to our RoleLinkButtonClick event handler. We’ll add this to the if/then block that equals “EditRoleDescription”. We’ll add this right after we populate our textbox with the role description and use the textbox’s text rather than using the GetRoleDescription function and round-tripping the database again. Add the following line:

lblOldRoleDescription.Text = txtRoleDescription.Text

Finally, we’ll raise our Role Description Changed event in the lnkRoleDescriptionSave_Click event handler. We’ll add it inside our if/then statement that checks if our rename was successful. If we’re in the first half of the if/then statement, we know that we were successful, so as the first line in the true block, raise our event as follows:

RaiseEvent RoleChanged(Me, New RoleChangedEventArgs _
      (RoleChangedEventArgs.RoleChangedEventActions.DescriptionChanged, _
        New RoleChangedEventArgs.RoleChangedEventActionArgs _
        (lblRoleDescriptionName.Text, "", lblOldRoleDescription.Text, _
        txtRoleDescription.Text)))

Lastly, we’ll raise our event for user being assigned/unassigned from a role. Some of our role manipulation is done in our in private subroutine UpdateRoleMembership. We’ll have to do a little more than just raise our event, we’ll want to store the roles as they are added and removed, so we’ll add two variables just outside our for/next loop defined as lists of string as follows:

Dim ojbAddedRoles As New List(Of String)
Dim objRemovedRoles As New List(Of String)

We’ll then add a line to each block of the if/then statements, one for when a role is added (in the added block):

objAddedRoles.Add(theCheckbox.Text)

and one to the removed block:

objRemovedRoles.Add(theCheckbox.Text)

After the end of the for/next loop, we’ll raise our event. Between the end sub and the next, add our call:

RaiseEvent UserRoleAssignmentChanged(Me, _
                         New RoleUserAssignmentArgs(objAddedRoles.ToArray(), _ 
                         objRemovedRoles.ToArray(), theUser))

We have to convert our list (of) variables to arrays since that’s what we’re passing. I chose to pass arrays rather than lists so any person using the control won’t have to worry about importing the System.Collections.Generic namespace.

We’ll also need to raise our events in our ChangeUserIsAssignedToRole subroutine. This is where we will assign the user to a particular role rather than assigning roles to users (When editing assignments from the role side rather than the user side). We’ll need to add two calls, one in our if/then block’s true block as follows, just after the Role.AddUserToRole call:

RaiseEvent UserRoleAssignmentChanged(Me, _
                             New RoleUserAssignmentArgs(New String() _
                      {lblRoleToAddRemoveUsersTo.Text}, Nothing, theLabel.Text))

The other we’ll add in the else block, just after the RemoveUserFromRole call:

RaiseEvent UserRoleAssignmentChanged(Me, _
                 New RoleUserAssignmentArgs(Nothing, New String() _
                 {lblRoleToAddRemoveUsersTo.Text}, theLabel.Text))

You’ll notice that our EventArgs is expecting an array, however, we are passing a single role rather than multiple so, we have to create an array and populate it with our single role. The other array that isn’t being used is set to nothing.

NOTE: the functionality of the UpdateRoleMembership subroutine needs to be changed a little to facilitate the UserRoleAssignmentChanging event. Please see these modifications in the comments.

Epilogue

There we go. Now when we perform specific actions using our control, we can report to the developer using it that the event happened and the developer can take extra actions without having to delve into the UserControl’s code and ripping it apart. Besides, it’s better encapsulation to do it this way – best practices and all.

Hopefully, we won’t run into any more things that need added ;-)

Posted: Thursday, February 24, 2011 11:54 AM by Yougotiger

Comments

Yougotiger said:

** Author's Note: **

The main reason that I added events to this control in the first place was so that I could address an actual need in my development work. I needed to perform some other steps once a user was deleted. Specifically, I needed to delete an entry in another table, a subscriptions table when the user was deleted. The entry in that table contains the user's email address - but no other identifying information. The problem lies in this. The UserDeleted event returns the USERNAME, but now that the user is deleted, I cannot retrieve the email from the username. So, I added a UserDeleting event where I CAN retrieve this information and do the removal, and then allow the user to be deleted.

You'll notice that in the code above, there are several lines in red/bold indicating the inclusion of this new event.

# March 31, 2011 2:18 PM

Yougotiger said:

** Author's Note: **

I decided that I needed to have a UserRoleAssignmentChanging event so that I could call cancel on it if I so desired. To do this I had to make some changes. First I added a definition for a UserRoleAssignmentChanging event in the section with all the other events. You'll see that it uses a new type of event Args, RoleUserAssignmentChangingArgs. This is basically the same as the RoleUserAssignmentChangedArgs with the addition of a Cancel property. This can be set to true and then checked later to cancel the update. This class is also defined and can be found above in red.

Finally, I had to modify the guts of the UpdateRoleMembership subroutine to perform the new functionality. Rather than give the specifics of the change, I'll just include the final code of what I ended up with. My UpdateRoleMembership subroutine now looks like this:

Private Sub UpdateRoleMembership(ByVal theRepeater As Repeater, ByVal theUser As String)

       If String.IsNullOrEmpty(theUser) Then Exit Sub

       Dim objAddedRoles As New List(Of String)

       Dim objRemovedRoles As New List(Of String)

       For Each rptItem As RepeaterItem _

                            In theRepeater.Items

           Dim theCheckbox As CheckBox = _

      CType(rptItem.FindControl("chkRole"), CheckBox)

           If theCheckbox.Checked = True AndAlso _

     Roles.IsUserInRole(theUser, theCheckbox.Text) _

        = False Then

               'Roles.AddUserToRole(theUser, theCheckbox.Text)

               objAddedRoles.Add(theCheckbox.Text)

           End If

           If theCheckbox.Checked = False AndAlso Roles.IsUserInRole(theUser, theCheckbox.Text) = True Then

               'Roles.RemoveUserFromRole(theUser, theCheckbox.Text)

               objRemovedRoles.Add(theCheckbox.Text)

           End If

       Next

       Dim objArgs As New _ RoleUserAssignmentChangingArgs(objAddedRoles.ToArray(), objRemovedRoles.ToArray(), theUser)

       RaiseEvent UserRoleAssignmentChanging(Me, objArgs)

       If Not objArgs.Cancel Then

           For Each sAddedRole As String In objAddedRoles

               Roles.AddUserToRole(theUser, sAddedRole)

           Next

           For Each sRemovedRole As String In objRemovedRoles

               Roles.RemoveUserFromRole(theUser, sRemovedRole)

           Next

           RaiseEvent UserRoleAssignmentChanged(Me, New RoleUserAssignmentChangedArgs(objAddedRoles.ToArray(), objRemovedRoles.ToArray(), theUser))

       End If

   End Sub

Basically what happens is rather than calling the add/remove from roles right away, I pack all the information up and pass it to the event. The Changing event is called and if after the return the cancel property is false, THEN I process the add/remove stuff.

One note, becuase this is subroutine is called as part of a larger process (editing the user), even if the role stuff is canceled, the user will get the alert that things were changed successfully becuase - they were. OTHER changes to the user weren't canceled, just the role assignment changes.

# June 6, 2011 12:20 PM
Leave a Comment

(required) 

(required) 

(optional)

(required) 

Enter the code you see below

Comment Notification

If you would like to receive an email when updates are made to this post, please register here

Subscribe to this post's comments using RSS