views:

2016

answers:

3

Hello,

I am going round in circles and need some help in implementing a Custom MembershipUser so that I can add my own custom Properties to the MembershipUser.

I have been following the example on this site: How to: Implement a Custom Membership User

The problem I am having is in the constructor of CustomMembershipUser, I think.

My CustomMembershipUser has these three additional Properties: firstName, middleName, lastName.

public class CustomMembershipProvider : MembershipProvider
{
  public override MembershipUser GetUser(string username, bool userIsOnline)
    {
       //.... Get data from database
       MembershipUser baseUser = new MembershipUser(this.Name,
                                               username,
                                               userId,
                                               email,
                                               "",
                                               comment,
                                               isApproved,
                                               isLockedOut,
                                               dtCreate,
                                               dtLastLogin,
                                               dtLastActivity,
                                               DateTime.Now,
                                               dtLastLockoutDate);
                    return new CustomMembershipUser(baseUser, firstName, middleName, lastName)
    }
}


public class CustomMembershipUser : MembershipUser
{
  private string _firstName;
    public string FirstName { get { return _firstName; } set { _firstName = value; } }

    private string _middleName;
    public string MiddleName { get { return _middleName; } set { _middleName = value; } }

    private string _lastName;
    public string LastName { get { return _lastName; } set { _lastName = value; } }

 public CustomMembershipUser(MembershipUser baseuser, string firstname, string middlename, string lastname)
    {
        _firstName = firstname;
        _middleName = middlename;
        _lastName = lastname;

        new CustomMembershipUser(baseuser); // DO I NEED THIS?? HOW TO IMPLEMENT??

    }
}

I am calling it like so:

    MembershipUser mu = Membership.GetUser(UserName);

    CustomMembershipProvider p = (CustomMembershipProvider)Membership.Provider;

    MembershipUser memUser = p.GetUser(UserName, true);

    object userId = memUser.ProviderUserKey;

The ProviderUserKey is null and so are the other values.

How can I obtain the addition Properties I added?

Thanks

+4  A: 

Based on my own experience trying to do much of the same, trying to use the MembershipProvider to do this will be an ultimately frustrating and counterintuitive experience.

The idea of the membership provider model isn't to change or augment what the definition of a user is, as you're trying to do - it is to allow the Framework an alternate means of accessing the information that has already been defined as belonging to a "MembershipUser".

I think what you're really looking for is a user profile. Using ASP.NET profiles is boatloads easier than implementing your own provider. You can find the overview here.

Daniel Schaffer
+1 for the overview. Also, you may want to look at the OdeToCode article below. It provides an example of how to use the Profile class in a manner similar to what you have described.http://www.odetocode.com/articles/440.aspx
Matthew Jones
I'm using the profile provider for associating first and last names with membership users. It has a few annoying characteristics, but overall it's a fast way to integrate profile functionality into your app that's using membership.
I Have the Hat
A: 

Just so you know, I've tried to go down the MembershipProvider path before, and it's a long and windy one. You might see if just creating classes that implement IPrincipal and IIdentity will satisfy your needs, since they entail a lot less overhead.

Brian Sullivan
+2  A: 

Hi picflight,

This is working for me:

public class CustomMembershipUser : MembershipUser
{
    public CustomMembershipUser(
     string providerName,
     string name,
     object providerUserKey,
     string email,
     string passwordQuestion,
     string comment,
     bool isApproved,
     bool isLockedOut,
     DateTime creationDate,
     DateTime lastLoginDate,
     DateTime lastActivityDate,
     DateTime lastPasswordChangedDate,
     DateTime lastLockoutDate
     )
     : base(providerName, name, providerUserKey, email, passwordQuestion,
     comment, isApproved, isLockedOut, creationDate, lastLoginDate,
     lastActivityDate, lastPasswordChangedDate, lastLockoutDate)
    {
    }

    // Add additional properties
    public string CustomerNumber { get; set; }

}

public class CustomMembershipProvider : MembershipProvider
{

 public override MembershipUser GetUser(string username, bool userIsOnline)
 {
  if (string.IsNullOrEmpty(username))
  {
   // No user signed in
   return null;
  }

  // ...get data from db

  CustomMembershipUser user = new CustomMembershipUser(
     "CustomMembershipProvider",
     db.Username,
     db.UserId,
     db.Email,
     "",
     "",
     true,
     false,
     db.CreatedAt,
     DateTime.MinValue,
     DateTime.MinValue,
     DateTime.MinValue,
     DateTime.MinValue);

  // Fill additional properties
  user.CustomerNumber = db.CustomerNumber;

  return user;

 }

}

// Get custom user (if allready logged in)
CustomMembershipUser user = Membership.GetUser(true) as CustomMembershipUser;

// Access custom property
user.CustomerNumber
Jimmy
Jimmy,Thank you!! Your example made things clearer and now I implementation is working. Can you please post the code for the constructor of your CustomMembership?Thanks to the others who have provided guidance on using Profiles and sharing your experiences.
Picflight
*sigh*... you can lead a horse to water...
Daniel Schaffer
Picflight, I'm not really sure what you mean by the "constructor for the CustomMembership". My CustomerMembershipProvider class does not have a constructor.
Jimmy
I'd like to point out for anyone else finding this question that even though this is the "accepted" answer, this is *NOT* the correct way to go about accomplishing this task - any additional properties belonging to a user should be stored in a profile, which lets you accomplish this and much more with far less effort and without breaking the model like the code shown here does. See my answer below for more information.
Daniel Schaffer
Daniel, I might be mistaken here but I think that my solution is the correct one if you already have users in some custom table. If you didn't have any users then you probably wouldn't need to implement the custom provider in the first place and the Profile would be a convenient method for storing extra user information. How would you sync the profile if the underlying custom user table changes?
Jimmy
If he's still in the stages of writing the membership provider, that would lead me to believe there isn't any data yet. Regardless, using the tools that are already available, even if it means spending a little time up front refactoring, will ultimately save time and make the code more maintainable. With profiles, if you're using the default profile, you don't need to change the DB every time you add a property. With this solution, if you add a property, you need to change the database AND the membership provider, requiring a recompilation. With profiles, it's just a configuration change.
Daniel Schaffer
I understand the flexibility that profiles provide and I have used several times for standalone application. However, if your user data, including custom properties, belongs to some other system and changes outside your control I would not use profiles. Mainly because of the sync issues. If this system needs another custom property that no other system using the custom table needs, I would use profiles.
Jimmy