As developers begin shifting to ASP.NET 2.0, one of the biggest hurdles they will face is understanding the multitude of choices they now have and the implications of those choices on their design. Case and point, Profile. The Profile feature in ASP.NET gives you a simple way of defining database-backed user profile information. It is similar to Session in many ways since it is data stored per client, but it has the advantage of always being written to and read from a database, thus avoiding many of the issues with session state (like its lack of durability or its inability to scale to a web farm deployment).
Here's a small example of using profile to give you an idea. First, declare the properties you would like to store on behalf of each user in your web.config file under the <profile> element:
<configuration xmlns="http://schemas.microsoft.com/.NetConfiguration/v2.0">
<system.web>
<profile>
<properties>
<add name="firstname" type="System.String" />
<add name="lastname" type="System.String" />
<add name="age" type="System.Int32" />
</properties>
</profile>
</system.web>
</configuration>
When ASP.NET compiles your site, it creates a new class that derives from HttpProfileBase with typesafe accessors to the properties you declared. These accessors use the profile provider to save and retrieve these properties to and from whatever database the provider is configured to interact with. Here's what the generated class looks like for the properties declared above:
namespace ASP
{
public class HttpProfile : HttpProfileBase
{
public virtual string lastname
{
get
{
return ((string)(this.GetPropertyValue("lastname")));
}
set
{
this.SetPropertyValue("lastname", value);
}
}
public virtual string firstname
{
get
{
return ((string)(this.GetPropertyValue("firstname")));
}
set
{
this.SetPropertyValue("firstname", value);
}
}
public virtual int age
{
get
{
return ((int)(this.GetPropertyValue("age")));
}
set
{
this.SetPropertyValue("age", value);
}
}
public virtual ASP.HttpProfile GetProfile(string username)
{
return ((ASP.HttpProfile)(System.Web.Profile.HttpProfileBase.Create(username)));
}
}
}
The second thing that happens, is ASP.NET adds a property declaration to each generated Page class in your site named 'Profile' which is a typesafe accessor to the current profile class (which is part of the HttpContext):
public partial class Default_aspx : Page
{
protected ASP.HttpProfile Profile
{
get { return ((ASP.HttpProfile)(this.Context.Profile)); }
}
//...
}
This lets you interact with your profile properties in a very convenient way, for example, here's an example of setting the profile properties based on fields in a form:
void enterButton_Click(object sender, EventArgs e)
{
Profile.firstname = firstNameTextBox.Text ;
Profile.lastname = lastNameTextBox.Text ;
Profile.age = int.Parse(ageTextBox.Text);
}
If you look in the database used by the profile provider (currently an Access .mdb file by default), you will see a table called aspnet_Profile with 4 columns:
UserId
PropertyNames
PropertyValuesString
LastUpdatedDate
In our example above, these columns were populated with the following values:
1
firstname:S:0:3:lastname:S:3:5:age:S:8:2:
JoeSmith22
9/28/2004 8:27:12 AM
So you can see that the Profile provider uses a string serialization with property names and string lengths carefully stored as well on a per-user basis.
What concerns me about this model, is that it is extremely convenient to use, but it produces a very chatty interface with the database with data that is basically an opaque blob to anyone but the profile provider itself (meaning no stored procs can interact with the data, nor can you do join queries across tables using profile information). Every time you use the Profile object to access/set a property, you incur a round trip the database.
You can ameliorate the inefficiency somewhat this somewhat by defining your own classes (like Person) and storing instances of classes in profile instead of individual values, but at that point it feels like you are designing a data access layer and you may as well go all the way and forego Profile altogether.
In the end, I'd have to recommend that people use this feature for quick prototyping and/or sites where scalability and carefully designed database schema are not a concern (like for your local tennis tournament :) If people feel otherwise, I'd be interested in hearing why.
[One last note - there is a nice feature of profile that lets you store data on behalf of anonymous users and then migrate that data to a known user once then log in or create an account, but that's still not enough for me to recommend using it for large scale sites.]
Posted
Sep 28 2004, 06:55 AM
by
fritz-onion