Shining Star Services LLC

Creating a Custom Membership Provider and Membership User utilizing a Data Set Table Adapter - Step 6

by Nannette Thacker

Adding Properties to Our Custom MembershipProvider Class

We now want to setup our properties for our custom SSSMembershipProvider class. In the below block of code, we will define variables to use in pulling the properties as setup within the web.config file:

#Region "Properties from web.config"
    ' Properties from web.config, default all to False
    Private m_EnablePasswordReset As Boolean = False
    Private m_EnablePasswordRetrieval As Boolean = False
    Private m_RequiresQuestionAndAnswer As Boolean = False
    Private m_RequiresUniqueEmail As Boolean = False
    Private m_ApplicationName As String = String.Empty
    Private m_PasswordStrengthRegularExpression As String = String.Empty
    Private m_MaxAllowedPasswordLength As Integer = 0
    Private m_MaxInvalidPasswordAttempts As Integer = 0
    Private m_MinRequiredNonAlphanumericCharacters As Integer = 0
    Private m_MinRequiredPasswordLength As Integer = 0
    Private m_PasswordAttemptWindow As Integer = 10
    Private m_PasswordFormat As System.Web.Security.MembershipPasswordFormat = MembershipPasswordFormat.Clear
#End Region
You don't have to setup a #Region, but #Regions help to separate sections within your class to make your code more readable. You may use the + and - symbols in the left column of your code to display and hide regions:



Click the minus symbol to hide the region:



We now want to redefine our ApplicationName property:

#Region "ApplicationName."
    Public Overrides Property ApplicationName() As String
        Get
            Return m_ApplicationName
        End Get
        Set(ByVal value As String)
            m_ApplicationName = value
        End Set
    End Property
#End Region
Although for the purposes of this tutorial, we won't use the majority of properties, they must be included as part of the class, so we will go ahead and set them up for your future purposes. Replace the existing Password properties with the following region:

#Region "Password Properties."

    Public Overrides ReadOnly Property EnablePasswordReset() As Boolean
        Get
            Return m_EnablePasswordReset
        End Get
    End Property

    Public Overrides ReadOnly Property EnablePasswordRetrieval() As Boolean
        Get
            Return m_EnablePasswordRetrieval
        End Get
    End Property

    Public ReadOnly Property MaxAllowedPasswordLength() As Integer
        Get
            Return m_MaxAllowedPasswordLength
        End Get
    End Property

    Public Overrides ReadOnly Property MaxInvalidPasswordAttempts() As Integer
        Get
            Return m_MaxInvalidPasswordAttempts
        End Get
    End Property

    Public Overrides ReadOnly Property MinRequiredNonAlphanumericCharacters() _
        As Integer
        Get
            Return m_MinRequiredNonAlphanumericCharacters
        End Get
    End Property

    Public Overrides ReadOnly Property MinRequiredPasswordLength() As Integer
        Get
            Return m_MinRequiredPasswordLength
        End Get
    End Property

    Public Overrides ReadOnly Property PasswordAttemptWindow() As Integer
        Get
            Return m_PasswordAttemptWindow
        End Get
    End Property

    Public Overrides ReadOnly Property PasswordFormat() _
        As System.Web.Security.MembershipPasswordFormat
        Get
            Return m_PasswordFormat
        End Get
    End Property

    Public Overrides ReadOnly Property PasswordStrengthRegularExpression() _
        As String
        Get
            Return m_PasswordStrengthRegularExpression
        End Get
    End Property

    Public Overrides ReadOnly Property RequiresQuestionAndAnswer() As Boolean
        Get
            Return m_RequiresQuestionAndAnswer
        End Get
    End Property

#End Region
If you get a squiggly line under any of your properties, it may indicate that you have it defined twice.



Simply highlight and remove the original declarations. In the below screen shot, I am highlighting the second duplicate declaration in order to delete it.



Add another Region for the Email properties:

#Region "Email Properties."
    Public Overrides ReadOnly Property RequiresUniqueEmail() As Boolean
        Get
            Return m_RequiresUniqueEmail
        End Get
    End Property
#End Region
Before setting up our Initialize function, we will add a helper function to retrieve our web.config configuration settings.

#Region "GetConfigValue."
    ' Pass in configuration value from the web.config. 
    ' Check if it has been defined, if not use the default value as passed in.
    Private Function GetConfigValue(ByVal configValue As String, _
        ByVal defaultValue As String) As String
        If String.IsNullOrEmpty(configValue) Then _
           Return defaultValue
        Return configValue
    End Function
#End Region
You are now ready to add the #Region for the initialization function. In the example Initialize function, we will check if there is a configuration file, set a name for the provider, and initialize the abstract base class. We then retrieve the values defined in the web.config file and define the password format. We do not need to setup a database connection, because we are using datasets.

#Region "Initialization."

    Public Overrides Sub Initialize(ByVal name As String, _
        ByVal config As System.Collections.Specialized.NameValueCollection)

        If config Is Nothing Then _
            Throw New ArgumentNullException("SSSMembershipProvider.Initialize: config is null.")

        If String.IsNullOrEmpty(name) Then _
            name = "SSSMembershipProvider"

        ' Initialize the abstract base class.
        MyBase.Initialize(name, config)

        m_ApplicationName = GetConfigValue(config("applicationName"), "/")
        m_EnablePasswordReset = Convert.ToBoolean(GetConfigValue(config("enablePasswordReset"), "False"))
        m_EnablePasswordRetrieval = Convert.ToBoolean(GetConfigValue(config("enablePasswordRetrieval"), "False"))
        m_RequiresQuestionAndAnswer = Convert.ToBoolean(GetConfigValue(config("requiresQuestionAndAnswer"), "False"))
        m_RequiresUniqueEmail = Convert.ToBoolean(GetConfigValue(config("requiresUniqueEmail"), "False"))
        m_PasswordStrengthRegularExpression = _
        Convert.ToString(GetConfigValue(config("passwordStrengthRegularExpression"), ""))
        m_MaxInvalidPasswordAttempts = Convert.ToInt32(GetConfigValue(config("maxInvalidPasswordAttempts"), "5"))
        m_PasswordAttemptWindow = Convert.ToInt32(GetConfigValue(config("passwordAttemptWindow"), "10"))
        m_MinRequiredNonAlphanumericCharacters = _
        Convert.ToInt32(GetConfigValue(config("minRequiredAlphaNumericCharacters"), "0"))
        m_MinRequiredPasswordLength = Convert.ToInt32(GetConfigValue(config("minRequiredPasswordLength"), "1"))
        m_MaxAllowedPasswordLength = Convert.ToInt32(GetConfigValue(config("MaxAllowedPasswordLength"), "10"))

        Dim temp_format As String = config("passwordFormat")
        If String.IsNullOrEmpty(temp_format) Then
            temp_format = "clear"
        End If
        Select Case temp_format.ToLower
            Case "hashed"
                Throw New Exception("MemberProvider.Initialize: Hashed passwords are not supported.")
            Case "encrypted"
                m_PasswordFormat = MembershipPasswordFormat.Encrypted
            Case "clear"
                m_PasswordFormat = MembershipPasswordFormat.Clear
            Case Else
                Throw New ProviderException("Password format not supported.")
        End Select

    End Sub

#End Region
Another thing we should do before we begin creating the GetUser, ValidateUser, and CreateUser methods is to clean up the methods we do not intend to implement. In this case, we'll create a new region for our non-implemented methods and throw an exception for each unimplemented method. After working through this tutorial, you may add coding for each method as you use them.

#Region "Non-Implemented MembershipProvider Methods"
    Public Overrides Function ChangePasswordQuestionAndAnswer(ByVal username As String, _
    ByVal password As String, ByVal newPasswordQuestion As String, ByVal newPasswordAnswer As String) As Boolean
        Throw New Exception("ChangePasswordQuestionAndAnswer: This method is not implemented.")
    End Function
    Public Overrides Function DeleteUser(ByVal username As String, _
    ByVal deleteAllRelatedData As Boolean) As Boolean
        Throw New Exception("DeleteUser: This method is not implemented.")
    End Function
    Public Overrides Function FindUsersByEmail(ByVal emailToMatch As String, _
    ByVal pageIndex As Integer, ByVal pageSize As Integer, ByRef totalRecords As Integer) _
    As System.Web.Security.MembershipUserCollection
        Throw New Exception("FindUsersByEmail: This method is not implemented.")
    End Function
    Public Overrides Function FindUsersByName(ByVal usernameToMatch As String, _
    ByVal pageIndex As Integer, ByVal pageSize As Integer, ByRef totalRecords As Integer) _
    As System.Web.Security.MembershipUserCollection
        Throw New Exception("FindUsersByName: This method is not implemented.")
    End Function
    Public Overrides Function GetAllUsers(ByVal pageIndex As Integer, _
    ByVal pageSize As Integer, ByRef totalRecords As Integer) _
    As System.Web.Security.MembershipUserCollection
        Throw New Exception("GetAllUsers: This method is not implemented.")
    End Function
    Public Overrides Function GetNumberOfUsersOnline() As Integer
        Throw New Exception("GetNumberOfUsersOnline: This method is not implemented.")
    End Function
    Public Overrides Function GetPassword(ByVal username As String, _
    ByVal answer As String) As String
        Throw New Exception("GetPassword: This method is not implemented.")
    End Function
    Public Overrides Function GetUserNameByEmail(ByVal email As String) As String
        Throw New Exception("GetUserNameByEmail: This method is not implemented.")
    End Function
    Public Overrides Function ResetPassword(ByVal username As String, _
    ByVal answer As String) As String
        Throw New Exception("ResetPassword: This method is not implemented.")
    End Function
    Public Overrides Function UnlockUser(ByVal userName As String) As Boolean
        Throw New Exception("UnlockUser: This method is not implemented.")
    End Function
    Public Overrides Sub UpdateUser(ByVal user As System.Web.Security.MembershipUser)
        Throw New Exception("UpdateUser: This method is not implemented.")
    End Sub
#End Region
We are now ready to begin Step 7: Step 7: Creating Our Custom MembershipUser Class..

Steps for Creating a Custom Membership Provider and Membership User utilizing a DataSet Table Adapter:

Introduction: Creating a Custom Membership Provider and Membership User utilizing a DataSet Table Adapter.
Step 1: Creating the Project and Folders.
Step 2: Table Data Structure and Web.config for this Tutorial.
Step 3: Creating The DataSet.
Step 4: Creating the Table Adapter Methods for GetUserByLogin, GetUserByUserName, and InsertUser.
Step 5: Creating our Custom MembershipProvider Class.
Step 6: Adding Properties to Our Custom MembershipProvider Class.
Step 7: Creating Our Custom MembershipUser Class.
Step 8: Customizing our MembershipProvider Class.
Step 9: Our Custom RoleProvider Class.
Step 10: Our Master page.
Step 11: Our Cookie Handler class.
Step 12: Our Log In page.
Step 13: Our Register page.
Step 14: Our Log Out page.
Step 15: Our Change Password page.
Step 16: Our Administration page.
Step 17: Loading a Menu Programmatically based on Roles.
Step 18: Our Default page.
Download the ZIP files:
VB: ShiningStarCustomMemberProviderTutorial.zip
© Copyright 1997-2017 Shining Star Services LLC, Nannette Thacker. All Rights Reserved.