When the ASP.NET team set out to build the ASP.NET Personalization system, the most challenging aspect of the design was the data model. They wanted to allow for the maximum amount of flexibility and extensibility. They initially examined several approaches with schemas within the database to describe properties and their types but found that this created very deep tables that couldn't efficiently be used without an intimate knowledge of the schema. They were also concerned that this approach would not perform well. They ideally desired for the data model to use the columns for each type of data, for example, a FirstName column of type nvarchar(256). While this gave them the best performance, it was the most difficult to extend; extensibility would have consisted of adding columns and tables. They decided on an approach that gave the end developer the most flexibility; hence the provider design pattern was created. The provider pattern allows you to store or use data in any shape and use the friendly, easy-to-use Personalization APIs. In fact, they want you to write providers. Most developers already have lots of user data. Rather than forcing you to use a new data model, the provider pattern allows the data to remain in whatever format you desire , but at the same time you can easily expose that data through the Personalization APIs. All providers must implement IProvider as well as the specific feature interface. For Personalization this is System.Configuration.Settings .ISettingsProvider . Earlier in the chapter we discussed a Personalization provider for the ASP.NET Forums; Listing 7.13 shows a simple implementation of that Personalization provider. Listing 7.13 Sample Personalization ProviderImports System Imports System.Web Imports System.Collections Imports System.Collections.Specialized Imports System.Configuration.Provider Imports System.Configuration.Settings Imports System.Web.Personalization Imports System.Data Imports System.Data.SqlClient Namespace Forums Public Class ForumsPersonalizationProvider Implements IProvider, ISettingsProvider Public Sub Initialize(name As String, _ config As NameValueCollection) _ Implements IProvider.Initialize ' Used to set the name and any ' config data from configuration End Sub ' Returns property values Public Sub GetPropertyValues (userName As String, _ Properties As SettingsPropertyCollection) _ Implements ISettingsProvider.GetPropertyValues Dim connection As SqlConnection Dim command As SqlCommand connection = New SqlConnection("connection string") command = New SqlCommand("SELECT * FROM Users " _ & "WHERE Username = '" _ & userName & "'", connection) Dim reader As SqlDataReader connection.Open() reader = command.ExecuteReader() While reader.Read() properties("Email").PropertyValue = reader("Email") properties("FakeEmail").PropertyValue = reader("FakeEmail") properties("Trusted").PropertyValue = reader("Trusted") properties("DateCreated").PropertyValue = reader("DateCreated") properties("TotalPosts").PropertyValue = reader("TotalPosts") End While connection.Close() End Sub Public Sub SavePropertyValues (userName As String, _ properties As SettingsPropertyCollection, _ isAuthenticated As Boolean) _ Implements ISettingsProvider.SavePropertyValues End Sub Public Property ApplicationName() As String _ Implements ISettingsProvider.ApplicationName Get return "/" End Get Set (ByVal Value As String) End Set End Property Public ReadOnly Property Name() As String _ Implements IProvider.Name Get return "ForumsProvider" End Get End Property End Class End Namespace Once compiled, we can use this provider by specifying it in our web.config , as demonstrated in Listing 7.14. Listing 7.14 Adding the Custom Provider<configuration> <system.web> <personalization> <providers> <add name="ForumsProvider" type="Forums.ForumsPersonalizationProvider, ForumsPersonalizationProvider" applicationName="/" /> </providers> <profile> <property name="FirstName"/> <property name="LastName" /> <property name="Email" provider="ForumsProvider" /> <property name="FakeEmail" provider="ForumsProvider" /> <property name="Trusted" type="System.Boolean" provider="ForumsProvider" /> <property name="DateCreated" type="System.DateTime" provider="ForumsProvider" /> <property name="TotalPosts" type="System.Int32" provider="ForumsProvider" /> </profile> </personalization> </system.web> </configuration> Finally, we can then write pages that display the property values (see Listing 7.15). Listing 7.15 Using the Custom ProviderYour email address is: <% =Profile.Email %> <P> Your fake email address is: <% =Profile.FakeEmail %> <P> Your total posts are: <% =Profile.TotalPosts %> <P> Your account was created: <% =Profile.DateCreated.ToString("MM/dd/yy mm:ss")%> Providers allow you to fully plug in to the APIs exposed by ASP.NET. You can take full control over what happens when those APIs are used within your application. |