Creating Custom Personalization Providers


The Web Part Framework uses the Provider Model to save personalization information. The default and only Personalization Provider included with the framework is the SqlPersonalizationProvider. The beautiful thing about the Provider Model is that if you don't like anything about the default provider, then you can easily create your own custom provider.

In this section, we create two custom personalization providers: a Query String Personalization Provider and a Anonymous Personalization Provider.

Building a Query String Personalization Provider

Personalization information, by default, is scoped against a particular page path. A user can personalize two different pages in two different ways. However, a user cannot personalize the same page in two different ways.

For some applications, this limitation might present a problem. For example, imagine that you are creating an online store that includes a Product.aspx page. This page displays information on different products, depending on the value of a Query String passed to the page.

Note

Another approach to solving the problem discussed in this section is to create a VirtualPathProvider. This option is discussed in Chapter 19, "Advanced Navigation."


The SqlPersonalization provider does not enable you to customize the page differently, depending on the product ID passed to the page. To enable users to personalize different versions of the same product page, you need to create a custom Query String Personalization Provider.

This project contains the following two pages:

  • MovieList.aspx This page displays a list of movies. Clicking a movie links to the MovieDetails.aspx page, with the movie ID passed as a query string parameter.

  • MovieDetails.aspx This Web Part page displays information on a particular movie.

The project also includes the following two Web Parts:

  • MoviePart.ascx Displays details for a particular movie.

  • TextPart.ascx Displays a block of text.

Finally, the project contains the following two support files:

  • QueryStringPersonalizationProvider This class implements the custom personalization provider.

  • Web.Config This configuration file configures the custom personalization provider.

All the files listed here are contained on the CD that accompanies the book. In this section, we concentrate on the QueryStringPersonalizationProvider class, which is contained in Listing 29.11.

Listing 29.11. QueryStringPersonalizationProvider.vb

[View full width]

Imports System Imports System.Web Imports System.Web.UI.WebControls.WebParts Namespace myControls     ''' <summary>     ''' Custom personalization provider which takes into account the     ''' id query string parameter.     ''' </summary>     Public Class QueryStringPersonalizationProvider         Inherits SqlPersonalizationProvider         ''' <summary>         ''' Called when data is saved to the database         ''' </summary>         Protected Overrides Sub SavePersonalizationBlob(ByVal webPartManager As   WebPartManager, ByVal path As String, ByVal userName As String, ByVal dataBlob() As Byte)             Dim queryStringId As String = HttpContext.Current.Request("id")             If Not queryStringId Is Nothing Then                 path += "?0" width="14" height="9" align="left" src="/books/3/444/1/html/2/images/ccc.gif" /> WebPartManager, ByVal path As String, ByVal userName As String, ByRef sharedDataBlob() As  Byte, ByRef userDataBlob() As Byte)             Dim queryStringId As String = HttpContext.Current.Request("id")             If Not queryStringId Is Nothing Then                 path += "?0" width="14" height="9" align="left" src="/books/3/444/1/html/2/images/ccc.gif" /> sharedDataBlob, userDataBlob)         End Sub         ''' <summary>         ''' Called when a user's personalization data is reset         ''' </summary>         Protected Overrides Sub ResetPersonalizationBlob(ByVal webPartManager As   WebPartManager, ByVal path As String, ByVal userName As String)             Dim queryStringId As String = HttpContext.Current.Request("id")             If Not queryStringId Is Nothing Then                 path += "?docText">The class in Listing 29.11 overrides three methods of the base SqlPersonalizationProvider class: the SavePersonalizationBlob(), LoadPersonalizationBlob(), and ResetPersonalizationBlob() methods. The Blob, in this context, refers to the serialized blob of personalization data.

In each of these methods, the value of the query string parameter named ID is added to the path associated with the state data being saved. In other words, the state data is scoped to the path and ID query string parameter.

After you add the class in Listing 29.11 to your application's App_Code folder, you need to configure the custom personalization provider. The Web configuration file in Listing 29.12 configures the QueryStringPersonalizationProvider as the application's default personalization provider.

Listing 29.12. Web.Config

<?xml version="1.0"?> <configuration xmlns="http://schemas.microsoft.com/.NetConfiguration/v2.0">   <connectionStrings>     <add       name="Northwind"       connectionString="Server=localhost;Trusted_Connection=true; Database=Northwind"/>   </connectionStrings>     <system.web>       <webParts>         <personalization           defaultProvider="QueryStringPersonalizationProvider">           <providers>             <add               name="QueryStringPersonalizationProvider"               type="myControls.QueryStringPersonalizationProvider"               connectionStringName="localSQLServer" />           </providers>         </personalization>       </webParts>     </system.web> </configuration> 

CD Note

The Web.Config file in this section is named Web.Config_listing12 on the CD so that it does not interfere with the other code samples in this chapter.


You can test the QueryStringPersonalizatonProvider by opening the MovieList.aspx page on the CD that accompanies this book in your browser. When you click on a movie title, you are linked to the MovieDetails.aspx page, which displays a particular movie. Notice that you can personalize each version of the MovieDetails.aspx page differently. For example, you can enter different text in the TextPart control for each movie (see Figure 29.6 and Figure 29.7), even though the different movies are displayed by the same page.

Figure 29.6. Displaying Star Wars movie details.


Figure 29.7. Displaying Jaws movie details.


Building an Anonymous Personalization Provider

The default SqlPersonalizationProvider stores personalization data for a user only when the user is authenticated. This requirement makes sense. Typically, you do not want to store personalization data for every random stranger who visits your website.

However, there are situations in which you might want to enable anonymous users to personalize a Web Part application. For example, you might want to create a customizable portal page, such as those used for My MSN or My Yahoo, and not require users to register at your website prior to performing the customization.

Fortunately, modifying the existing SqlPersonalizationProvider to support anonymous users is not that difficult because another part of the ASP.NET Framework already includes the infrastructure for identifying anonymous users. The ASP.NET Framework supports a feature called Anonymous Identification, which is used to support anonymous ASP.NET Profiles.

Note

The Profile class is discussed in Chapter 22, "Maintaining Application State."


In this section, you learn how to create an Anonymous Personalization Provider. To create this custom personalization provider, you need to modify three of the standard classes used by the Web Part Framework.

First, you need to create the Anonymous Personalization Provider class itself. This class is contained in Listing 29.13.

Listing 29.13. AnonSqlPersonalizationProvider.vb

[View full width]

Imports System Imports System.Web Imports System.Web.UI.WebControls.WebParts Namespace myControls     ''' <summary>     ''' Custom Personalizaton Provider which enables     ''' anonymous personalization     ''' </summary>     Public Class AnonSqlPersonalizationProvider         Inherits SqlPersonalizationProvider         ''' <summary>         ''' Saves personalization data to the database         ''' </summary>         Protected Overrides Sub SavePersonalizationBlob(ByVal webPartManager As   WebPartManager, ByVal path As String, ByVal userName As String, ByVal dataBlob() As Byte)             If Not HttpContext.Current.Request.IsAuthenticated Then                 userName = HttpContext.Current.Request.AnonymousID             End If             MyBase.SavePersonalizationBlob(webPartManager, path, userName, dataBlob)         End Sub         ''' <summary>         ''' Loads personalization data from the database         ''' </summary>         Protected Overrides Sub LoadPersonalizationBlobs(ByVal webPartManager As   WebPartManager, ByVal path As String, ByVal userName As String, ByRef sharedDataBlob() As  Byte, ByRef userDataBlob() As Byte)             If Not HttpContext.Current.Request.IsAuthenticated Then                 userName = HttpContext.Current.Request.AnonymousID             End If             MyBase.LoadPersonalizationBlobs(webPartManager, path, userName, sharedDataBlob , userDataBlob)         End Sub         ''' <summary>         ''' Deletes personalization data from the database         ''' </summary>         Protected Overrides Sub ResetPersonalizationBlob(ByVal webPartManager As   WebPartManager, ByVal path As String, ByVal userName As String)             If Not HttpContext.Current.Request.IsAuthenticated Then                 userName = HttpContext.Current.Request.AnonymousID             End If             MyBase.ResetPersonalizationBlob(webPartManager, path, userName)         End Sub         ''' <summary>         ''' Determines whether the page opens in User or Shared         ''' personalization scope         ''' </summary>         Public Overrides Function DetermineInitialScope(ByVal webPartManager As  WebPartManager, ByVal loadedState As PersonalizationState) As PersonalizationScope             Return webPartManager.Personalization.InitialScope         End Function     End Class End Namespace 

The AnonPersonalizationProvider overrides four methods of the base SqlPersonalizationProvider class. If a user is anonymous, then the LoadPersonalizationBlob(), SavePersonalizationBlob(), and ResetPersonalizationBlob() methods use the anonymous ID associated with the user rather than the normal username. The DetermineInitialScope() method is also overridden because the default implementation of this method automatically puts anonymous users into Shared personalization scope.

Next, you need to modify the standard WebPartPersonalization class. The standard version of this class prevents anonymous users from modifying state information. The updated AnonWebPartPersonalization class is contained in Listing 29.14.

Listing 29.14. AnonWebPartPersonalization.vb

[View full width]

Imports System Imports System.Collections Imports System.Web Imports System.Web.UI.WebControls.WebParts Namespace myControls     ''' <summary>     ''' Overrides the standard WebPartPersonalization class     ''' to enable anonymous users to modify state.     ''' </summary>     Public Class AnonWebPartPersonalization         Inherits WebPartPersonalization         Public Sub New(ByVal webPartManager As WebPartManager)             MyBase.New(webPartManager)         End Sub         Protected Overrides ReadOnly Property UserCapabilities() As IDictionary             Get                 If HttpContext.Current.Request.IsAuthenticated = True Then                  Return MyBase.UserCapabilities                 Else                  Dim capabilities As Hashtable = New Hashtable()                  capabilities.Add(WebPartPersonalization.ModifyStateUserCapability,  WebPartPersonalization.ModifyStateUserCapability)                     Return capabilities                 End If             End Get         End Property     End Class End Namespace 

In Listing 29.14, the UserCapabilities property is overridden. The new version of this property ensures that all users, even anonymous users, have the capability to modify state information.

Next, because a custom WebPartPersonalization class has been created, the standard WebPartManager control has to be modified before you can use it. The updated WebPartManager control is contained in Listing 29.15.

Listing 29.15. AnonWebPartManager.vb

Imports System Imports System.Web.UI.WebControls.WebParts Namespace myControls     ''' <summary>     ''' Modifies the base WebPartManager control     ''' to use the AnonWebPartPersonalization class     ''' </summary>     Public Class AnonWebPartManager         Inherits WebPartManager         Protected Overrides Function CreatePersonalization() As WebPartPersonalization             Return New AnonWebPartPersonalization(Me)         End Function     End Class End Namespace 

In Listing 29.15, the base CreatePersonalization() method of the WebPartManager control is overridden to use the custom AnonWebPartPersonalization class.

Next, you are ready to enable the Anonymous Personalization Provider. The web configuration file in Listing 29.16 contains the necessary configuration settings.

Warning

You might need to restart your application to load the new personalization provider.


Listing 29.16. Web.Config

<?xml version="1.0"?> <configuration xmlns="http://schemas.microsoft.com/.NetConfiguration/v2.0">         <system.web>                 <anonymousIdentification enabled="True"/>                 <authentication mode="None" />                 <webParts>                         <personalization defaultProvider="AnonProvider">                                 <providers>                                         <add             name="AnonProvider"             type="myControls.AnonSqlPersonalizationProvider"             connectionStringName="localSQLServer"/>                                 </providers>                                 <authorization>           <allow users="Administrators" verbs="enterSharedScope"/>                                 </authorization>                         </personalization>                 </webParts>                 </system.web> </configuration> 

CD Note

The configuration file in Listing 29.16 is saved with the name Web.Config_listing16 on the CD so that it does not interfere with the other code samples in this chapter.


The Web configuration file in Listing 29.16 does three things. First, it enables Anonymous Identification. When this feature is enabled, a GUID is generated automatically for each user and stored in a browser cookie. Second, the configuration file disables authentication by setting the Authentication Mode to the value None. Finally, the configuration file configures the AnonPersonalizationProvider as the default personalization provider for the application.

Warning

You might need to restart your application to load the new personalization provider.


At this point, it's finally time to try out the Anonymous Personalization Provider. The Web Form page in Listing 29.17 can be customized by strangers.

Listing 29.17. TestAnonymous.aspx

<%@ Page Language="VB" %> <%@ Register TagPrefix="custom" Namespace="myControls" %> <%@ Register TagPrefix="user" TagName="PersonalizationManager"    src="/books/3/444/1/html/2/~/PersonalizationManager.ascx" %> <%@ Register TagPrefix="user" TagName="TextPart" src="/books/3/444/1/html/2/~/TextPart.ascx" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"    "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"> <script runat="server">     Protected Sub Menu1_MenuItemClick(ByVal sender As Object, ByVal e As MenuEventArgs)         WebPartManager1.DisplayMode = WebPartManager1.DisplayModes(e.Item.Text)     End Sub </script> <html xmlns="http://www.w3.org/1999/xhtml" > <head  runat="server">     <style type="text/css">         .personalizationManager         {             border:dotted 2px orange;             padding:5px;             background-color:White;             font:12px Arial, Sans-Serif;         }         .personalizationManager span         {             padding-right:10px;             margin-right:10px;             border-right:solid 1px black;         }         .personalizationManager a         {             text-decoration:none;         }         .column         {             float:left;             width:30%;             height:200px;             margin-right:10px;             border:solid 1px black;             background-color: white;         }         .menu         {             margin:5px 0px;         }         html         {             background-color:#eeeeee;         }     </style>     <title>Anonymous Personalization</title> </head> <body>     <form  runat="server">     <custom:AnonWebPartManager                  Runat="server" />     <user:PersonalizationManager                  runat="server" />         <asp:Menu                          OnMenuItemClick="Menu1_MenuItemClick"             Orientation="Horizontal"             Css             Runat="server">             <Items>             <asp:MenuItem Text="Browse" />             <asp:MenuItem Text="Design" />             </Items>         </asp:Menu>         <asp:WebPartZone                          Css             Runat="server">             <ZoneTemplate>             <user:TextPart                                  Title="Text Part"                 Description="Displays block of text"                 Runat="server" />             </ZoneTemplate>         </asp:WebPartZone>         <asp:WebPartZone                          Css             Runat="server" />     </form> </body> </html> 

After you open the page in Listing 29.17, you can update the text displayed by the TextPart Web Part (see Figure 29.8). If you close your browser and return to the website in two years, the same text will appear.

Figure 29.8. Using the Anonymous Personalization Provider.


If you want to simulate two anonymous users, then you need to open two different types of browsers (opening multiple instances of Internet Explorer doesn't work because they all share the same browser cookies). For example, you can open the Default.aspx page in both Internet Explorer and Mozilla Firefox and make different changes to the same page.

Warning

There is one undesirable consequence of the way that the Anonymous Personalization Provider was implemented in this chapter. Anonymous users are added to the aspnet_Users database table without being marked as anonymous. To fix this problem you need to modify the following line in the aspnet_PersonalizationPerUser_SetPageSettings stored procedure:

EXEC dbo.aspnet_Users_CreateUser @ApplicationId, @UserName, 0, @CurrentTimeUtc, @UserId OUTPUT


The 0 parameter hard codes all users as authenticated.





ASP. NET 2.0 Unleashed
ASP.NET 2.0 Unleashed
ISBN: 0672328232
EAN: 2147483647
Year: 2006
Pages: 276

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net