Get all user profiles with all custom properties with ASP.NET Membership

Jim Noble picture Jim Noble · Sep 19, 2012 · Viewed 7.4k times · Source

I am creating an MVC4 web application that uses ASP.NET forms authentication with custom profile properties defined, such as first and last name.

After some wrangling, this is working well for the logout widget:

Hello, 

@((Profile as ProfileCommon).FirstName)

@((Profile as ProfileCommon).LastName)

But now I need to make an administrative screen that displays (among other things) the first and last name of all of the author for a list of documents.

This is for displaying a grid of information, so I can't make a database-bound call for every user for performance reasons. I need to get all of the information in one or two queries.

I have the author's membership user ID GUID for each row. So I need to get all of the users' first and last names keyed off of the GUID.

After reviewing some other SO posts on this topic, I have come up with this static method to get the information:

public static IEnumerable<UserInfo> GetUserInfos()
{
    var members = Membership.GetAllUsers();

    var profiles = ProfileManager.GetAllProfiles(ProfileAuthenticationOption.All);

    foreach (MembershipUser member in members)
    {
        var profile = profiles[member.UserName];

        if (profile != null)
        {
            yield return new UserInfo
            {
                UserId = (Guid)member.ProviderUserKey,

                FirstName = profile.???,

                LastName = profile.???
            };
        }
    }
}

I am getting the members and profiles from the methods successfully. But all of the profile objects are ProfileInfo objects, and not ProfileCommon or ProfileBase. They do not appear to have any way to access the custom properties.

Why are the custom properties missing from this technique? How can I get them?

Is there a better or easier way of doing this?

For reference, pertinent web.config values:

<authentication mode="Forms">
    <!--<forms name=".ASPXAUTH" protection="None" domain=".napa-ibs.com" path="/" loginUrl="Account/Login" />-->
    <forms name=".ASPXAUTH" protection="None" path="/" loginUrl="Account/Login" />
</authentication>
<roleManager enabled="true">
    <providers>
        <clear/>
        <add
            name="AspNetSqlRoleProvider"
            connectionStringName="AuthenticationDatabase"
            applicationName="IBSRegistration"
            type="System.Web.Security.SqlRoleProvider, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"/>
    </providers>
</roleManager>
<membership>
    <providers>
        <clear/>
        <add
            name="AspNetSqlMembershipProvider"
            type="System.Web.Security.SqlMembershipProvider, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"
            connectionStringName="AuthenticationDatabase"
            enablePasswordRetrieval="true"
            enablePasswordReset="true"
            requiresQuestionAndAnswer="false"
            applicationName="IBSRegistration"
            requiresUniqueEmail="false"
            passwordFormat="Clear"
            maxInvalidPasswordAttempts="100"
            minRequiredPasswordLength="7"
            minRequiredNonalphanumericCharacters="1"
            passwordAttemptWindow="10"/>
    </providers>
</membership>
<profile enabled="true">
    <providers>
        <clear/>
        <add
            name="AspNetSqlProfileProvider"
            connectionStringName="AuthenticationDatabase"
            applicationName="IBSRegistration"
            type="System.Web.Profile.SqlProfileProvider, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"/>
    </providers>
    <properties>
        <add name="FirstName" type="string"/>
        <add name="LastName" type="string"/>
        <add name="Title" type="string"/>
        <add name="District" type="string"/>
        <add name="DC" type="string"/>
        <add name="Address1" type="string"/>
        <add name="Address2" type="string"/>
        <add name="City" type="string"/>
        <add name="State" type="string"/>
        <add name="ZipCode" type="string"/>
        <add name="IsApproved" type="bool"/>
        <add name="RegistrationDate" type="DateTime"/>
    </properties>
</profile>

Answer

Phaedrus picture Phaedrus · Sep 19, 2012

You will need to get a reference to a CommonProfile object to access your custom properties.

public static IEnumerable<UserInfo> GetUserInfos()
{
    var members = Membership.GetAllUsers();

    var profiles = ProfileManager.GetAllProfiles(ProfileAuthenticationOption.All);

    foreach (MembershipUser member in members)
    {
        var profile = profiles[member.UserName];
        ProfileCommon profileCommon = Profile.GetProfile(profile.UserName);

        if (profileCommon != null)
        {
            yield return new UserInfo
            {
                UserId = (Guid)member.ProviderUserKey,

                FirstName = profileCommon.FirstName,

                LastName = profileCommon.LastName
            };
        }
    }
}