Custom Membership Provider Using Additional Functions

Last post 07-07-2009 11:29 AM by papabear. 11 replies.

Sort Posts:

  • Custom Membership Provider Using Additional Functions

    07-02-2009, 5:31 PM

    I have built a custom membership provider that inherits from the MembershipProvider class. In my custom provider, I have defined a few new functions that I need to use, but my issue is that I can't access those functions on the front end using the Membership namespace.

    So in my default.aspx code behind, I would like to call a function GetUserIDFromUserName() by just typing Membership.GetUserIDFromUserName().

    In order for me to be able to do that right now, I have to cast Membership to my custom provider like this

    Dim mem As ccMembershipProvider = CType(Membership.Provider, ccMembershipProvider)


    In my web.config I have the following code

    <membership defaultProvider="ccMembershipProvider">
    			<providers>
    				<clear/>
    				<add name="ccMembershipProvider" type="cc.Providers.ccMembershipProvider, cc" passwordFormat="Clear" connectionStringName="SQLConnectionString" applicationName="/" />
    			</providers>
    		</membership>
    How can I make it so Membership is pulling from my class that is inheriting from that without having to cast it to my provider every time?

    Filed under:
  • Re: Custom Membership Provider Using Additional Functions

    07-03-2009, 1:22 AM
    • Contributor
      5,222 point Contributor
    • RickNZ
    • Member since 01-01-2009, 3:43 AM
    • Nelson, New Zealand
    • Posts 863

    Would an extension method work for you?

    Something like this:

    public static class MyProvider
    {
        public static string GetUserIDFromUserName(this Provider prov, string name)
        {
            . . .
        }
    }


    That would let you call Provider.GetUserIDFromUserName(), as an instance method (not a static method).


  • Re: Custom Membership Provider Using Additional Functions

    07-03-2009, 8:49 AM

    Thanks for your reply Rick,

    I tried what you suggested, and I still can't call the function from the Membership keyword.

    The only way I can successfuly call my custom functions is if I cast Membership to my custom membership provider.

    Any other suggestions?

  • Re: Custom Membership Provider Using Additional Functions

    07-03-2009, 10:28 AM
    • Contributor
      5,222 point Contributor
    • RickNZ
    • Member since 01-01-2009, 3:43 AM
    • Nelson, New Zealand
    • Posts 863

    Can you post your code?

    Extension methods only work from class instances.  You can't add new static methods, and you can't instantiate the Membership class itself (all of its methods are static).  So, it wouldn't be Membership.YourMethod().  It would probably be:

    Membership.Provider.YourMethod();

    With YourMethod() as an extension method of MembershipProvider.

    Maybe not as clean as you were hoping, but it should still avoid a cast....




  • Re: Custom Membership Provider Using Additional Functions

    07-03-2009, 4:56 PM

    Here is the snippit of my custom membership provider


    Namespace Providers
    Public Class ccMembershipProvider
            Inherits MembershipProvider
    
            Private ReadOnly Property connectionString() As String
                Get
                    Return _sqlConnectionString
                End Get
            End Property
    
            Public Function GetUserIDByUsername(ByVal Username As String) As Guid
                Using ccData As New Data.ccDataContext(connectionString)
                    Dim usrID = (From m In ccData.Members _
                                  Where m.UserName = Username _
                                  Select m.UserId).SingleOrDefault()
                    Return usrID
                End Using
            End Function
    
    End Class
    End Namespace

    In the web.config...

    		<membership defaultProvider="ccMembershipProvider">
    			<providers>
    				<clear/>
    				<add name="ccMembershipProvider" type="cc.Providers.ccMembershipProvider, cc" passwordFormat="Clear" connectionStringName="ccSQL" applicationName="/" />
    			</providers>
    		</membership>


    And this is how I currently have to call it...


    Dim mem As ccMembershipProvider = CType(Membership.Provider, ccMembershipProvider)
    mem.GetUserIDByUsername("username")


    The rest of my custom membership provider is basically just all the other MustOverride Functions that I have put code into that I need. When I call something like Membership.GetUserNameByEmail(Email), that works fine because it's part of the base Membership class. It's just the custom functions I make that I can't do it.

    If I can get it to a point where I can just call Membership.Provider.GetUserIDByUsername("username"), that would be awesome.

    Thanks for your help looking into this.


  • Re: Custom Membership Provider Using Additional Functions

    07-03-2009, 5:01 PM

    Double post, sorry...

  • Re: Custom Membership Provider Using Additional Functions

    07-03-2009, 7:27 PM
    • Contributor
      5,222 point Contributor
    • RickNZ
    • Member since 01-01-2009, 3:43 AM
    • Nelson, New Zealand
    • Posts 863

    My VB is pretty weak, but you could try something like the following, although you'll need to make the connectionString property static:

    Imports System.Runtime.CompilerServices
    
    Module Extensions
             Private ReadOnly Property connectionString() As String  
                 Get  
                     Return _sqlConnectionString  
                 End Get  
             End Property  
     
             <Extension()>
             Sub GetUserIDByUsername(ByVal MembershipProvider prov,
                 ByVal Username As String) As Guid  
                 Using ccData As New Data.ccDataContext(connectionString)  
                     Dim usrID = (From m In ccData.Members _  
                                   Where m.UserName = Username _  
                                   Select m.UserId).SingleOrDefault()  
                     Return usrID  
                 End Using  
             End Sub
    End Module
      


  • Re: Custom Membership Provider Using Additional Functions

    07-06-2009, 9:10 AM

    Hey Rick,

    I'm tried using your suggestion, but I'm not sure it does what I was expecting.

    In order to call that function on the front end, I would have to do something like

    Extensions.GetUserIDByUsername("username", Membership.Provider)


    Right?

    I have spent a lot of time looking into this and it seems like the Membership Provider just can't be extended to allow for other functions to be added to it from the Membership namespace. I assume this is the same for the Roles and Profile Providers as well.

    What does the <Extension()> do for me in the code you provided? I am still not able to call Membership.Provider.GetUserIDByUsername.

    Maybe I just expected the Membership Provider to be more extensible than it is?

    Thanks again for your help Rick!

  • Re: Custom Membership Provider Using Additional Functions

    07-07-2009, 1:36 AM
    • Contributor
      5,222 point Contributor
    • RickNZ
    • Member since 01-01-2009, 3:43 AM
    • Nelson, New Zealand
    • Posts 863

    The <Extension()> attribute tells the compiler that the method is an extension method.  You definitely should not have to call it as you said in your post.

    It should be Membership.Provider.GetUserByName("username");

    If it compiles the way you had it, then you have the arguments backwards.  The class to which the extension method should be added must be the first argument.

    Things to check:

    1. Make sure that the namespace/class in which the extension method is located can be referenced from the class where you're using it.

    2. Intellisense understands extension methods.  Type Membership.Provider.  -- and it should be listed there.  If it isn't, then something isn't set up right.

    If that doesn't work, post your code for the extension method and I'll take a look.

  • Re: Custom Membership Provider Using Additional Functions

    07-07-2009, 9:54 AM

    Hey Rick,

    I guess my problem is that I don't know where to put this module and how that module is associated with the Membership provider.

    After doing some more research, I now know that I can't add functions to the Membership Provider because it's not meant to be extended like that.

    I still can't get it to be called by doing the Membership.Provider.GetUserIDFromUsername() call.

    I think I'm just spending too much time caring about how this function is called when I can just cast my Membership Provider and deal with it. I just expected the Base Membership Provider to be more extensible I guess.


  • Re: Custom Membership Provider Using Additional Functions

    07-07-2009, 11:11 AM
    Answer
    • Contributor
      5,222 point Contributor
    • RickNZ
    • Member since 01-01-2009, 3:43 AM
    • Nelson, New Zealand
    • Posts 863

    You can put the module anywhere, as long it can be referenced (implicitly!) from the class where you want to call it (through an appropriate Imports statement, for example).  Extension methods are "magic" that way.

    Here's are a couple of links that describe them in more detail; maybe they will help:

    http://msdn.microsoft.com/en-us/magazine/cc163317.aspx

    http://blogs.msdn.com/vbteam/archive/2007/01/05/extension-methods-part-1.aspx

    Your comment about extensibility is correct.  It's a characteristic of the language, though, more than that particular code.

    FWIW, I made a test extension method (in C#) for MembershipProvider, and it worked fine...  One quick test you might try is to see if the extension method shows up in Intellisense from within the extension method itself.  If not, then you might have the function signature wrong.


  • Re: Custom Membership Provider Using Additional Functions

    07-07-2009, 11:29 AM
    Answer
    • Contributor
      5,138 point Contributor
    • papabear
    • Member since 08-08-2005, 3:49 PM
    • Posts 851

    You can use it, but what you need to so is simply cast it as the appropriate class. Remember inheritance - your class can 'become' a Membership.Provider, but a Membership.Provider can NOT become your class...

    You HAVE to use your own class because of inheritance. No way around the concrete rules of OO...

    :)

    give me suggestions for what to blog... http://www.myfriedmind.com/techblog -> thx

    Mark as "Answered" if this solves that wee old problem...
Page 1 of 1 (12 items)