tags:

views:

60

answers:

1

I have a SQL database that is different than the one in ASP.net so I had to create a custom membership Provider. The provider to get the user looks like this: My SQL class name is CustomSqlProvider:

Public Overrides Function GetUser(ByVal username As String, _
    ByVal userIsOnline As Boolean) As MembershipUser
    'Dim connectionString As String = "Server=***;Database=***;User Id=***password=****"'

    Dim conn As SqlConnection = New SqlConnection(connectionString)
    Dim cmd As SqlCommand = New SqlCommand("Get_User", conn)
    cmd.CommandType = CommandType.StoredProcedure

    cmd.Parameters.Add("@UserName", SqlDbType.NVarChar)
    cmd.Parameters.Add("@Password", SqlDbType.NVarChar)

    Dim u As MembershipUser = Nothing
    Dim reader As SqlDataReader = Nothing

    Try
        conn.Open()

        If userIsOnline Then
            Dim updateCmd As SqlCommand = New SqlCommand("Update_User", conn)

            updateCmd.Parameters.Add("@UserName", SqlDbType.NVarChar)
            updateCmd.Parameters.Add("@F_Name", SqlDbType.NVarChar)
            updateCmd.Parameters.Add("@L_Name", SqlDbType.NVarChar)
            updateCmd.Parameters.Add("@PWD", SqlDbType.VarChar)
            updateCmd.Parameters.Add("@Email", SqlDbType.VarChar)

            updateCmd.ExecuteNonQuery()
        End If

    Catch e As SqlException
        'If WriteExceptionsToEventLog Then
        '    WriteToEventLog(e, "Get_User, as String")
        '    Throw New ProviderException(exceptionMessage)
        'Else
        'Throw e
        'End If
    Finally
        If Not reader Is Nothing Then reader.Close()

        conn.Close()
    End Try

    Return u
End Function

Public Overrides Function GetUser(ByVal providerUserKey As Object, _
    ByVal userIsOnline As Boolean) As MembershipUser

    Dim conn As SqlConnection = New SqlConnection(connectionString)
    Dim cmd As SqlCommand = New SqlCommand("Get_User", conn)
    cmd.CommandType = CommandType.StoredProcedure

    cmd.Parameters.Add("@UserId", SqlDbType.UniqueIdentifier).Value = providerUserKey

    Dim u As MembershipUser = Nothing
    Dim reader As SqlDataReader = Nothing

    Try
        conn.Open()

        reader = cmd.ExecuteReader()

        If reader.HasRows Then
            reader.Read()
            u = GetUserFromReader(reader)

            If userIsOnline Then
                Dim updateCmd As SqlCommand = New SqlCommand("Update_User", conn)

                updateCmd.Parameters.Add("@UserId", SqlDbType.UniqueIdentifier)


                updateCmd.ExecuteNonQuery()
            End If
        End If
    Catch e As SqlException
        If WriteExceptionsToEventLog Then
            WriteToEventLog(e, "GetUser(Object, Boolean)")

            Throw New ProviderException(exceptionMessage)
        Else
            Throw e
        End If
    Finally
        If Not reader Is Nothing Then reader.Close()

        conn.Close()
    End Try

    Return u
End Function

Now what I want to do is I first login to my website, it authenticates, and I am in. I am then redirected to another page where I can change my Username. But I can't seem to get the GUID of the logged in User in order to change it. I'm using a stored procedure that Updates the Users Table.

I have the following code on the Page where I can change credentials:

Dim currentUser as MembershipUser = Membership.GetUser() Dim CurrentUSerId as Guid = CType(currentUser.ProviderUserKey, Guid)

I get reference not set to an instance of an object. Any help would be appreciated.

Thank you for the edit. I have also added get and set properties so I can be able to add values to those parameters. The parameters in the Update_User sproc are inputs. My Get_User sproc looks like this..which is why I think it is not getting the GUID because when it is run it asks for Username and password and then it returns everything including the Guid back:

GO /** Object: StoredProcedure [dbo].[Get_User] Script Date: 07/14/2010 09:16:17 **/ SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO ALTER PROCEDURE [dbo].[Get_User] @UserName nvarchar(50), @Password varchar(50) AS SELECT USER_ID, USER_NAME, F_NAME, L_NAME, BUILDING_ID, SIP_ROLE, INTERNAL_ID, PWD, EMAIL FROM dbo.USERS WHERE USER_NAME = @UserName AND PWD = @Password RETURN

///////////////////////////////////////////////////////////////////////////////////////////

After adding those gets and sets and assigning parameter variables to my Sproc parameters I get the following error: "Reference not set to an instance of an object." at this line of code:

Dim currentUser As MembershipUser = Membership.GetUser() Dim UserId As Guid = CType(currentUser.ProviderUserKey, Guid)

And this is what I have on the UserInfo.aspx.vb Page under the Button click:

Dim sql As New SqlClient.SqlCommand("Update_User", con) sql.Parameters.Add("@UserId", SqlDbType.UniqueIdentifier).Value = UserId sql.Parameters.Add("@UserName", SqlDbType.NVarChar).Value = txtUserName.Text

A: 

In the first GetUser OverRide where does it execute the following line:

Dim cmd As SqlCommand = New SqlCommand("Get_User", conn)

I can't see that the command is executed, I have been known to be incredibly dumb though :)

Perhaps your code needs to follow the pattern in the Get_User by ProviderUserKey pattern, I've added some missing things and questions, hope this helps.

    Public Overrides Function GetUser(ByVal username As String, _
    ByVal userIsOnline As Boolean) As MembershipUser
    'Dim connectionString As String = "Server=***;Database=***;User Id=***password=****"'

    Dim conn As SqlConnection = New SqlConnection(connectionString)
    Dim cmd As SqlCommand = New SqlCommand("Get_User", conn)
    cmd.CommandType = CommandType.StoredProcedure

    cmd.Parameters.Add("@UserName", SqlDbType.NVarChar).Value = "??????"
    cmd.Parameters.Add(("@Password", SqlDbType.NVarChar).Value = "??????"

    Dim u As MembershipUser = Nothing
    Dim reader As SqlDataReader = Nothing

    Try
        conn.Open()
        reader = cmd.ExecuteReader()
        If reader.HasRows Then
            reader.Read()
            u = GetUserFromReader(reader)


            If userIsOnline Then
                Dim updateCmd As SqlCommand = New SqlCommand("Update_User", conn)
                'Are these input or output parameters?
                updateCmd.Parameters.Add("@UserName", SqlDbType.NVarChar).Value = u.UserName
                updateCmd.Parameters.Add("@F_Name", SqlDbType.NVarChar).Value = "??????"
                updateCmd.Parameters.Add("@L_Name", SqlDbType.NVarChar).Value = "??????"
                updateCmd.Parameters.Add("@PWD", SqlDbType.VarChar).Value = "??????"
                updateCmd.Parameters.Add("@Email", SqlDbType.VarChar).Value = "??????"

                updateCmd.ExecuteNonQuery()
            End If
        End If
    Catch e As SqlException
        'If WriteExceptionsToEventLog Then
        '    WriteToEventLog(e, "Get_User, as String")
        '    Throw New ProviderException(exceptionMessage)
        'Else
        'Throw e
        'End If
    Finally
        If Not reader Is Nothing Then reader.Close()

        conn.Close()
    End Try

    Return u
End Function
Simon Hazelton
Hmm it has it being executed after the connection is open at updateCmd.ExecuteNonQuery() after the Try
ssez
ok, that executes your updateCmd, but not the cmd itself. Looks like there are a few errors with your Parameters.Add calls as well. I believe that you specify the parameter name and the value you want to assign it.
Simon Hazelton
Alright so I added cmd.ExecuteNonQuery right after the parameters are added. When I try to select providerUserKey it comes out like this: providerUserKey:= (where I have to put in an expression) but all i want it to do is grab it not specify something else. Do I just add variables and assign them to the parameters? And do all the parameters I have in my Sproc have to be specified here too or just the ones I am looking for?
ssez
Also, I noticed in your edited code, you can't execute reader.ExecuteNonQuery because as an SqlDataReader it can only execute the Reader property. But maybe executeNonQuery is what I need and it won't work unless I put that specifically after the parameters.
ssez
oops, my bad :). You should use ExecuteReader. You need to retrieve the membership user to populate the fields of your update command. It's not the best way of achieving this but it will work
Simon Hazelton
Do you now have a custom User object as well? I don't think you'll find it easy to change all of the functionality of the MembershipUser. If I was trying to achieve what you are, I would look at storing the custom fields into Profile and using the built-in membership provider. In profile I would store FirstName, LastName, BuildingId, SIP_Role and InternalId. This would mean that you have hardly any custom code to write.
Simon Hazelton
I added First_Name, Last_Name, Building_Id as get set properties where the abstract base class of the custom membership provider is initialized. Our database very different from the ASP generic one so for example for my Update Parameters what values do I give them without using the Get and set of F_Name and L_Name, because overloading the GetUser Method does not work..it will only take in the same amount as the standard ASP membership. How would I add all my database fields like you said in the profile??
ssez