views:

597

answers:

3

So, I'm creating an ASP.NET MVC website.

It has a fairly complex user sign-up page with a lot of fields. My question is, where should I persist this? The user tables created by the membership-provider tool don't contain these columns and I'm left confused about what the best practice is in terms of storing this additional information about each user?

Is this where a profile provider comes into play? How do they work? If not, how else do you persist and store the additional user details not provided in the stock columns of the MembershipProvider tables?

Can anyone point me to some resources on how this is handled, how to access those additional user details when I need them, how to create a new user with all this information etc.

A: 

This article from CODE Magazine helped me with this issue.

George Stocker
+3  A: 

This is where the ASP.NET Profile provider comes in. You can use it to store whatever profile information you want about a user. All you need to do is add the fields you need in the web.config file, MSDN Link on how to configure the profile fields in web.config file. To sum the article up, you just add the name and type values you want to store to the properties node of the profile element. Here's an example:

<profile enabled="true">
  <properties>
    <add name="Name" />
    <group name="Address">
      <add name="Street" />
      <add name="City" />
      <add name="Zip" type="System.Int32" />
    </group>
  </properties>
</profile>

In ASP.NET Webforms, Visual Studio automagically creates a strongly typed profile class that will reference your custom profile properties. In MVC, this doesn't happen. To refer to a user's profile information, just call HttpContext.Profile["PropertyName"]. An example:

HttpContext.Profile["Name"] = name;
HttpContext.Profile.GetProfileGroup("Address")["Zip"] = zip;

Edit: As Andy noted, using the default SqlProfileProvider isn't really good if you want to run queries on these properties. He is completely right, and perhaps I should have originally noted this limitation. This limitation exists because SqlProfileProvider stores all of the profile data is in three columns: PropertyNames and PropertyValuesString/PropertyValuesBinary. All of the keys are stored in the PropertyNames field, values that can be stored as a string are stored in the PropertyValuesString field, etc. This means it's extremely hard to do a query like "Select * from aspnet_Profile where Age > 10".

Ryan Hoffman
+1  A: 

I'm not really sure there is a best practice and it really depends on how you want to use the information.

First, you have to recognize the membership and profiles are two separate things. The ASP.NET Membership, Profile, and Role functionality is designed to be used as a service, serving multiple sites/applications.

If you look at the schema for these relationships, you'll notice that users are unique to the system but a user can be shared across applications. That means that their profile information is shared across applications as well. Membership is actually the association of a user to an application and contains information about their relationship to that specific application (password, password Q&A, etc).

You can use the profile provider as Ryan suggested, but 1) that information isn't easily queried should you want to gather profile metrics and 2) it is shared across all consumers of the membership/profile services. You can, however, extend it to meet your needs.

You can extend the membership provider as Gortok suggested and that information would be relative to the application but you need to make sure you don't break existing consumers of the service by modifying the existing stored procedures or tables in a fashion that changes their interface or intent.

The other option is you can treat it as a service and track this information on your own, referencing into your own profile implementation using the user id from the asp.net sql provider.

There is a good series (16 parts) on Membership, Profiles, and Roles over at 4 Guys from Rolla that I'd recommend reading and then, once you're familiar with all of the moving parts, make an educated decision on where best to store and how best to structure the profile information you're looking to create.

andymeadows