10

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

Community
  • 1
  • 1
Picflight
  • 3,832
  • 13
  • 61
  • 90

3 Answers3

13

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
jimmystormig
  • 10,672
  • 1
  • 29
  • 28
  • 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 May 26 '09 at 20:43
  • Picflight, I'm not really sure what you mean by the "constructor for the CustomMembership". My CustomerMembershipProvider class does not have a constructor. – jimmystormig May 28 '09 at 07:22
  • 3
    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 May 28 '09 at 17:16
  • 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? – jimmystormig May 28 '09 at 20:13
  • 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 May 28 '09 at 22:38
  • 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. – jimmystormig May 29 '09 at 07:19
12

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
  • 56,753
  • 31
  • 116
  • 165
  • 1
    +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 May 26 '09 at 19:08
  • 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. – Rex Miller May 26 '09 at 19:11
3

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
  • 27,513
  • 23
  • 77
  • 91