Maximizing.ASP.dot.NET.Real.World.ObjectOriented.Development [Electronic resources]

Jeffrey Putz

نسخه متنی -صفحه : 146/ 102
نمايش فراداده

Profiles in Relation to Membership Records

As you learned in Chapter 11, "Membership and Security," the Membership system only stores basic user data for the purpose of authenticating a user. The realm of storing other data is a huge area to cover, as different applications have different needs. Fortunately, the Profile system will store whatever data you need, as configured by your web.config file. Using the default System.Web.Profile.SqlProfileProvider class, ASP.NET will store this data in the very same database used to store Membership data by default.

The same auto-generated SQL Server 2005 Express database used by SqlMembershipProvider is used by this provider and created in the /App_Data folder. As before, you can use the aspnet_regsql.exe utility to generate this database at another location.

Let's first look at the use of the Profile property without consideration for the underlying data store. This property is of the type HttpProfileBase and is a property of the HttpContext class (just like Request, Response, Session, and Cache, among others). The proper ties that are in turn available from Profile are generated at runtime (and design time, in Visual Studio) by reading them from web.config. Listing 12.1 shows a sample <profile> section from web.config.

Listing 12.1. The <profile> section of web.config
<?xml version="1.0" ?>
<configuration>
<system.web>
<profile defaultProvider="CustomProvider">
<providers>
<add name="CustomProvider" type="CustomProvider, MyAssembly" />
</providers>
<properties>
<add name="Happy" type="System.Boolean" />
<add name="HairColor" type="System.String" />
</properties>
</profile>
</system.web>
</configuration>

This very basic configuration creates two properties that we'll be able to set from code. The first one is called "Happy" and is of type Boolean, while the second one is called "HairColor" and is a string. Properties are listed between the properties elements. The providers that take care of the data plumbing are listed between the providers elements (more on providers in a minute). Figure 12.1 shows what happens in Visual Studio when we type a period after Profile.

Figure 12.1. Intellisense showing our Profile properties.

You can see that the two properties we declared in web.config appear for us, and because they're strongly typed, we know by mousing over the property that it's a Boolean or string (or whatever we declared it to be). When we try to read one of these properties, the provider tries to fetch the profile values from the database. After we change them, they are saved when we call Profile.Save().

In the profile element, we name a default provider, which must appear in the following providers section. The default SqlProfileProvider is assumed if you don't specify one.

If you'd like to further group your properties together, you can do so by enclosing them in a group. If you wanted to set up Profile.Pets.CatName, for example, you would set web.config as shown in Listing 12.2.

Listing 12.2. Grouping Profile properties
<?xml version="1.0" ?>
<configuration>
<system.web>
<profile>
<properties>
<add name="Happy" type="System.Boolean" />
<add name="HairColor" type="System.String" />
<group name="Pets">
<add name="CatName" type="System.String" />
</group>
</properties>
</profile>
</system.web>
</configuration>

Profile data is tied to the logged in user, as identified by User.Identity.Name. If you try to get profile data when no user is logged in and you aren't allowing for anonymous identification (more on that in a minute), you'll get an exception.

The profile system can also persist anonymous user data that's associated with the user's browser. By adding <anonymousIdentification enabled="true" /> between the <system.web> elements, a cookie is sent to the user for identification. Any properties that have their allowAnonymous attribute set to true will then be saved, and you won't get the error we described. In these cases, the user data is associated with the string set in the cookie (a Guid, actually) instead of User.Identity.Name. Listing 12.3 shows the Profile.Pets.CatName configured for anonymous use.

Listing 12.3. Enabling anonymous identification and profile properties
<?xml version="1.0" ?>
<configuration>
<system.web>
<anonymousIdentification enabled="true" />
<profile>
<properties>
<group name="Pets">
<add name="CatName" type="System.String" allowAnonymous="true" />
</group>
</properties>
</profile>
</system.web>
</configuration>

There are several other attributes that you can place in the anonymousIdentification tag that determine how the cookie is handled. Please consult the ASP.NET documentation for more information.

If you want a specific provider to handle a particular property, simply add a provider attribute to the add element and set it to the name of the provider in the providers section. This is a really useful feature because you can mix and match providers to handle data in different ways, potentially from totally separate data sources. For example, if CatName is handled by one provider but CarType would be handled by a different provider, you would add lines like this between the properties (or group) elements:

<add name="CatName" type="System.String" provider="MyAnimalProvider" />
<add name="CarType" type="System.String" provider="MyVehicleProvider" />

Profile's provider mechanism works just like Membership's does. An underlying class handles the plumbing between the class you use and the data store. In the case of the default SqlProfileProvider, profile data is stored in the default database or the database you specify as a combination of strings and binary objects, serializing the data as needed. The add elements in the <profile> section have an optional serializeAs attribute, which can be set to Binary, String, Xml, or ProviderSpecific. The first three will format the data as their names suggest, while the last will rely on the underlying provider to make the decision. Your own custom providers may choose to ignore this setting entirely, but that's up to you.