Recipe 10.3. Inheriting a Profile


Problem

You want to use ASP.NET 2.0's profile features but you do not want to define the profile information in the web.config file because you use the same profile definition in multiple applications.

Solution

Implement the membership features to provide user authentication, as described in Recipe 9.5, create a custom class that inherits from ProfileBase, add properties for each user-specific data item you want to include in the profile, and modify the <profile> element in web.config to set the inherits attribute to the custom class you created to store the user's profile data.

Use the .NET language of your choice to create a custom class for the profile data:

  1. Inherit from ProfileBase.

  2. Add a property for each data item to be included in the user profile

Modify web.config as follows:

  1. Add a <profile> element with a <provider> element defining the provider used to store and retrieve user-specific data.

  2. Set the inherits attribute of the <profile> element to the fully qualified namespace of the custom class you created.

Example 10-5 shows the modifications made to web.config for this solution. The custom user profile class is shown in Examples 10-6 (VB) and 10-7 (C#). The example page that uses the user profile information is identical to the example in Recipe 10.1 and is shown in Examples 10-2, 10-3 through 10-4.

Discussion

If you use the same user profile data in multiple applications, defining the profile in web.config creates a maintenance problem when any changes are required since the changes would have to be made in the web.config file of each application. Instead, defining the profile in a class that can be compiled into an assembly and then using the assembly in each application is a better solution. The profile infrastructure provided in ASP.NET 2.0 supports using a custom class for profile data to support this situation.

The custom profile class has three specific requirements. First, the class must inherit from ProfileBase. Second, the class must be serializable, meaning that all of the data in the class must be able to be serialized; most .NET data types can be serialized, so this is generally not an issue. Third, the class must include a property for each user profile data item to be stored. The class does not need to provide instance variables to store the class data. Instead, the data for each property must be accessed through the parent class, as shown below.

 

Public Property FirstName( ) As String Get Return CType(MyBase.Item("FirstName"), String) End Get Set(ByVal value As String) MyBase.Item("FirstName") = value End Set End Property

public String FirstName { get { return (String)(base["FirstName"]); } set { base["FirstName"] = value; } } // FirstName

The base class uses a collection of objects to store the property data using the name of the property. Since the data is stored as an <Object>, it must be cast to the appropriate data type when retrieving the data for a property.


The <profile> element in the web.config file for this solution includes an inherits attribute with the value set to the fully qualified namespace of the custom profile class. This provides the definition of the data the SqlProfileProvider will persist in the data store.

 <profile enabled="true"  defaultProvider="AspNetSqlProfileProvider"  inherits="ASPNetCookbook.VBExamples.UserProfile"  automaticSaveEnabled="false" >   <providers> <remove name="AspNetSqlProfileProvider" /> <add name="AspNetSqlProfileProvider"  type="System.Web.Profile.SqlProfileProvider"  connectionStringName="sqlConnectionString"  applicationName="/" />   </providers> </profile> 

In the custom profile class for our example, we have emulated the grouping functionality for properties described in Recipe 10.1. We have created a MailingAddress property with a data type of Address, and we have created an Address class with properties for Address1, Address2, City, State, and ZipCode. By using this approach, additional properties such as ShippingAddress can be added without having to define individual properties for each of the elements in an address. In addition, using this approach, the page used in Recipe 10.1 to demonstrate displaying and updating the profile data can be used with no changes.

See Also

Recipes 9.5 and 10.1

Example 10-5. Modifications to web.config to use an inherited profile

 <?xml version="1.0"?> <configuration>   <system.web> <!--    The <authentication> section enables configuration    of the security authentication mode used by    ASP.NET to identify an incoming user. --> <authentication mode="Forms" >   <forms name=".ASPNETCookbookVBPersonalization1" loginUrl="Login.aspx" protection="All" timeout="30" path="/" defaultUrl="UpdateProfile.aspx" /> </authentication> <authorization>   <deny users="*" /> <!-- Deny all users --> </authorization> <membership defaultProvider="AspNetSqlMembershipProvider" userIsOnlineTimeWindow="15">   <providers>     <remove name="AspNetSqlMembershipProvider" /> <add name="AspNetSqlMembershipProvider" type="System.Web.Security.SqlMembershipProvider" connectionStringName="sqlConnectionString" enablePasswordRetrieval="false" enablePasswordReset="true" requiresQuestionAndAnswer="true" applicationName="/" requiresUniqueEmail="false" minRequiredPasswordLength="4" minRequiredNonalphanumericCharacters="0" passwordFormat="Hashed" maxInvalidPasswordAttempts="5" passwordAttemptWindow="10" passwordStrengthRegularExpression="" />   </providers> </membership> <roleManager defaultProvider="AspNetSqlRoleProvider"     enabled="true" cacheRolesInCookie="true" cookieName=".ASPNETCookbookVBPersonalization2Roles" cookieTimeout="30" cookiePath="/" cookieRequireSSL="false" cookieSlidingExpiration="true" cookieProtection="All" >   <providers> <remove name="AspNetSqlRoleProvider" /> <add name="AspNetSqlRoleProvider" type="System.Web.Security.SqlRoleProvider" connectionStringName="sqlConnectionString" applicationName="/" />   </providers> </roleManager> <profile enabled="true"    defaultProvider="AspNetSqlProfileProvider" inherits="ASPNetCookbook.VBExamples.UserProfile" automaticSaveEnabled="false" > <providers>   <remove name="AspNetSqlProfileProvider" />   <add name="AspNetSqlProfileProvider" type="System.Web.Profile.SqlProfileProvider" connectionStringName="sqlConnectionString" applicationName="/" /> </providers> </profile>   </system.web>   <!--   ****************************************************************************     The following section defines the pages that require authentication for access. An entry must be included for each page that requires authentication with a list of the roles required for access to the page. Valid Roles are as follows. NOTE: The roles must be entered exactly as listed.   User   Admin   ****************************************************************************   -->   <location path="UpdateProfile.aspx"> <system.web>   <authorization>     <allow roles="User,     Admin"/> <deny users="*"/>   </authorization> </system.web>   </location> </configuration> 

Example 10-6. Custom profile class (.vb)

 Option Explicit On Option Strict On Namespace ASPNetCookbook.VBExamples   ''' <summary>   ''' This class provides a container for the the user's profile information   ''' </summary>   Public Class UserProfile Inherits ProfileBase '''********************************************************************** ''' <summary> ''' This property provides the ability to get/set the firstName ''' </summary> Public Property FirstName() As String   Get Return CType(MyBase.Item("FirstName"), String)   End Get   Set(ByVal value As String) MyBase.Item("FirstName") = value   End Set End Property '''********************************************************************** ''' <summary> ''' This property provides the ability to get/set the lastName ''' </summary> Public Property LastName() As String   Get Return CType(MyBase.Item("LastName"), String)   End Get   Set(ByVal value As String) MyBase.Item("LastName") = value   End Set End Property '''********************************************************************** ''' <summary> ''' This property provides the ability to get/set the mailing address ''' </summary> Public Property MailingAddress() As Address   Get Return CType(MyBase.Item("MailingAddress"), Address)   End Get   Set(ByVal value As Address) MyBase.Item("MailingAddress") = value   End Set End Property '''********************************************************************** ''' <summary> ''' This property provides the ability to get/set the email addresses ''' </summary> Public Property EmailAddresses() As StringCollection   Get Return CType(MyBase.Item("EmailAddresses"), StringCollection)   End Get   Set(ByVal value As StringCollection) MyBase.Item("EmailAddresses") = value   End Set End Property End Class 'UserProfile ''' <summary> ''' The following class is used as a data container for address data ''' </summary> Public Class Address Private mAddress1 As String Private mAddress2 As String Private mCity As String Private mState As String Private mZipCode As String '''********************************************************************** ''' <summary> ''' This property provides the ability to get/set the address1 ''' </summary> Public Property Address1() As String Get Return (mAddress1) End Get Set(ByVal value As String) mAddress1 = value End Set End Property '''********************************************************************** ''' <summary> ''' This property provides the ability to get/set the address2 ''' </summary> Public Property Address2() As String Get Return (mAddress2) End Get Set(ByVal value As String) mAddress2 = value End Set End Property '''********************************************************************** ''' <summary> ''' This property provides the ability to get/set the city ''' </summary> Public Property City() As String Get Return (mCity) End Get Set(ByVal value As String) mCity = value End Set End Property    '''********************************************************************** ''' <summary> ''' This property provides the ability to get/set the state ''' </summary> Public Property State() As String   Get Return (mState)   End Get   Set(ByVal value As String) mState = value   End Set End Property    '''********************************************************************** ''' <summary> ''' This property provides the ability to get/set the state ''' </summary> Public Property ZipCode() As String   Get Return (mZipCode)   End Get   Set(ByVal value As String) mZipCode = value   End Set End Property   End Class 'Address End Namespace 

Example 10-7. Custom profile class (.cs)

 using System; using System.Collections.Specialized; using System.Web.Profile; namespace ASPNetCookbook.CSExamples { /// <summary> /// This class provides a container for the the user's profile information. /// </summary> public class UserProfile : ProfileBase { ///********************************************************************** /// <summary> /// This property provides the ability to get/set the firstName /// </summary> public String FirstName { get {   return (String)(base["FirstName"]); } set {   base["FirstName"] = value; } } // FirstName ///********************************************************************** /// <summary> /// This property provides the ability to get/set the lastName /// </summary> public String LastName { get {   return (String)(base["LastName"]); } set {   base["LastName"] = value; } } // LastName ///********************************************************************** /// <summary> /// This property provides the ability to get/set the mailing address /// </summary> public Address MailingAddress { get {   return (Address)(base["MailingAddress"]); } set {   base["MailingAddress"] = value; } } // MailingAddress ///********************************************************************** /// <summary> /// This property provides the ability to get/set the email addresses /// </summary> public StringCollection EmailAddresses { get {   return (StringCollection)(base["EmailAddresses"]); } set {   base["EmailAddresses"] = value; } } // EmailAddresses } // UserProfile /// <summary> /// The following class is used as a data container for address data /// </summary> public class Address { private String mAddress1; private String mAddress2; private String mCity; private String mState; private String mZipCode; ///********************************************************************** /// <summary> /// This property provides the ability to get/set the address1 /// </summary> public String Address1 { get {   return (mAddress1); } set {   mAddress1 = value; } } // Address1 ///********************************************************************** /// <summary> /// This property provides the ability to get/set the address2 /// </summary> public String Address2 { get {   return (mAddress2); } set {   mAddress2 = value; } } // Address2 ///********************************************************************** /// <summary> /// This property provides the ability to get/set the city /// </summary> public String City { get {   return (mCity); } set {   mCity = value; } } // City ///********************************************************************** /// <summary> /// This property provides the ability to get/set the state /// </summary> public String State { get {   return (mState); } set {   mState = value; } } // State ///********************************************************************** /// <summary> /// This property provides the ability to get/set the state /// </summary> public String ZipCode { get {   return (mZipCode); } set {   mZipCode = value; } } // ZipCode } // Address } 



ASP. NET Cookbook
ASP.Net 2.0 Cookbook (Cookbooks (OReilly))
ISBN: 0596100647
EAN: 2147483647
Year: 2003
Pages: 202

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