Dealing With Members Using The MemberService & MembershipHelper

I'm an Umbraco fan, and I've been pretty vocal about that for years. However, since I started developing with it many years ago. My biggest annoyance was dealing with Members and how inefficient it was querying members that had lots of properties.

Lucky for us as part of the continuing Umbraco development cycle, the introduction of a number of new Services was added and one of these new services is the MemberService. Take this and throw in the MembershipHelper and we can now create large scale member driven sites, without having to worry as much about performance.

MemberService

You can use the MemberService for all CRUD (Although for creating new members via a registration form I'd use the MembershipHelper as shown below) but you have to remember it does hit the database for queries.

You can query for multiple members or just for a single member and it returns an IMember from the queries unlike the MembershipHelper below.

There does seem to be some caching for the queries, and you have a few helpful built in methods such as GetMembersByPropertyValue() which also has a number of overloads to deal with dates and match type (Exact, starts with etc.).

In Dialogue we use this service to query for multiple members, and also for updating and deleting members.

To access the MemberService you do it like so

ApplicationContext.Current.Services.MemberService

Some examples of use below that are taken from Dialogue, they should give you an idea of how you could use the service within your own application.

Query for members via a property value (Date Comparison)

var date = DateTime.UtcNow.AddMinutes(-AppConstants.TimeSpanInMinutesToShowMembers);
var members = ApplicationContext.Current.Services.MemberService.GetMembersByPropertyValue(AppConstants.PropMemberLastActiveDate, date, ValuePropertyMatchType.GreaterThan)
                .Where(x => x.IsApproved && !x.IsLockedOut);

Query for members via a property value (String - Starts with)

var members = ApplicationContext.Current.Services.MemberService.GetMembersByPropertyValue("PropMemberSlug", "some-string"), StringPropertyMatchType.StartsWith);

Query for members via a property value (String - Exact Match)

var members = ApplicationContext.Current.Services.MemberService.GetMembersByPropertyValue("PropMemberSlug", "some-string")

Update a property on the member

var member = ApplicationContext.Current.Services.MemberService.GetById(memberId);
member.Properties["PropMemberWebsite"].Value = "Add Me";
ApplicationContext.Current.Services.MemberService.Save(member);

MembershipHelper

Now I have to admit, this threw me a little when I started to use this. I assumed as it was using the cache that I'd be able to query for multiple members in a really efficient and quick way, but it only allows you to get members in a singular manner (GetByEmail, GetById etc...).

One thing you have to bear in mind is that when you use these methods you get an IPublishedContent back and not an IMember like you do with the MemberService above. You can then use the IPublishedContent to get the member property values just like you would for a normal content node (GetPropertyValue<string>("MyProperty") etc.).

To get the MembershipHelper you can do the following

var memHelper = new MembershipHelper(UmbracoContext.Current);

In Dialogue we use this helper class to get members individually along with their property values (As it's super quick), and also use it to register new members as it allows you to use the 'MembershipCreateStatus' so you can get back the status of the registration without having to write much of your own logic.

public enum MembershipCreateStatus
{
    Success,
    InvalidUserName,
    InvalidPassword,
    InvalidQuestion,
    InvalidAnswer,
    InvalidEmail,
    DuplicateUserName,
    DuplicateEmail,
    UserRejected,
    InvalidProviderUserKey,
    DuplicateProviderUserKey,
    ProviderError,
}

Registering a new Member

Below is the code on how we use the MembershipHelper to register a new member. We firstly create a RegisterModel and populate it with the data from our registration form.  This is a really simple model, containing Username, Password and email (And a few other things which are not important for this example)

var userToSave = memHelper.CreateRegistrationModel("MemberTypeAlias");
userToSave.Username = viewModel.UserName;
userToSave.Name = viewModel.Username;
userToSave.Email = viewModel.Email;
userToSave.Password = viewModel.Password;
userToSave.UsernameIsEmail = false;

Once the RegisterModel is created, we pass in a new MembershipCreateStatus along with the RegisterModel to a method in the MembershipHelper called 'RegisterMember' - this populates the MembershipCreateStatus and returns this with the status of the create.

MembershipCreateStatus createStatus;
memHelper.RegisterMember(userToSave, out createStatus, false);

Now we have this, we can choose how to proceed. We can check if the creation of the new member was successful or not

if (createStatus != MembershipCreateStatus.Success)
{
    // We could display the exact status of the issue
}
else
{
    // All fine - Continue
}

Getting a member and some properties

Below is an example showing the fastest why to get a member and their associated properties.

var member = memHelper.GetById(id);
var id = member.Id;
var username = member.Name;
var isApproved = member.GetPropertyValue("umbracoMemberApproved");
var isLockedOut = member.GetPropertyValue("umbracoMemberLockedOut");

If you would like to see more examples of using both the MemberService or the MembershipHelper then have a look at the Dialogue MemberService on GitHub 

https://github.com/leen3o/Dialogue/blob/master/Src/Dialogue.Logic/Services/MemberService.cs

Or just want to learn about Umbraco in general have a look at some of the videos we have on our Aptitude site.

Lee Messenger

Lee is on Twitter as