Monday, 21 December 2009

Reading the ProviderUserKey when using the SqlMembershipProvider

The ProviderUserKey gives access to a unique identifier for each of the members in your membership data store. If you're doing a large amount of lookup's or want to cross link to another table you will find this technique will give you better performance than using the UserName property.

If you are using the SqlMembershipProvider as your membership provider (which is the most common setup) you might find that you want to get at this unique user id. This is available via the ProviderUserKey property.

Because of the nature of the provider pattern this is implemented in a generic fashion as an Object data type and its not immediately obvious how you can get at the data.

A brief introduction to the provider pattern

The provider pattern is used in several areas of the .net library. The basic concept behind it is that a common interface is defined that all the different implementations have to follow. It doesn't matter how they implement it behind the scenes but you have to promise to implement all of the methods and properties defined in the provider.

This provides a consistent model to program against and has several benefits:

  1. The same code can be used in your programs without spreading provider specific code throughout your project
  2. The provider can be swapped out without having to change any client code
  3. Developers have skills that can be easily transferred between projects despite using different data stores
  4. New developers on the team can get up to speed with the code base very quickly

To get a clearer idea, some examples of membership provider implementations could be powered by a sql server database, oracle database, web service or even xml files. The code to implement all of these providers would look very different but the code to use it from the front end would all be the same. Microsoft asp.net ships with two providers by default, a SQL powered one and one that runs on top of an Active Directory.

The SqlMembershipProvider implementation

As you will see in the MSDN documentation the official data type is the .net base class Object. The individual provider is then free to implement their ProviderUserKey in any format which inherits from Object.

So as long at you know the data type being used by your provider you can simply cast the ProviderUserKey into the correct data type and read the information.

There is one final catch with the SqlMembershipProvider; it uses a GUID data type. The GUID doesn't have a parameterless constructor which means you cannot cast it directly, you have to new up an instance of the class. This is demonstrated in the code sample below:

MembershipUser currentUser = Membership.GetUser();
GUID userKey = null;

if(currentUser != null)
{
   userKey = new GUID(currentUser.ProviderUserKey);
}

Why would you use this information?

The ProviderUserKey is a unique identifier and is quicker to match than the UserName column. The ProviderUserKey is a uniqueidentifier sql datatype and the UserName is an nvarchar[255].

Also consider the situation where a user signs up to your website, contributes some content to the community and then closes their account. The username is available again which could mean that you end up attributing data from another users contributions to the wrong account. The ProviderUserKey is guaranteed to be a unique identifier.

Membership.GetUser()

Once you have a membership ProviderUserKey you can use it with the Membership.GetUser() method. An overload is provided which accepts this; Membership.GetUser(Object providerUserKey).

One possible scenario is that you store the retrieved GUID in a session variable at the start of a page and then each reload you have a quicker way of looking up the users details.

Further Reading

kick it Shout it vote it on WebDevVote.com

3 comments:

Anonymous said...

Just what I was looking for.

Thanks!

Abhijeet Kulkarni said...

But isn't it that .GetUser() requires two paramenters?

rtpHarry said...

@Abhijeet: If you call GetUser() without a parameter then it will populate a MembershipUser with the currently logged in users details.


-->