ASP.NET 2.0通过System.Web.HttpContext对象的Profile属性公开了其对用户配置的支持。Profile对象的核心就是System.Web.Profile.ProfileBase对象。可以在Web.config中配置Profile对象公开的属性名称和类型。在配置文件中,而不是在代码中定义的Profile对象的属性。只要ASP.NET运行你的应用程序,它都会查看Web.config中的用户配置属性配置,并且自动构建一个新的类,名为ProfileCommon,它从ProfileBase类继承而来,并且包含你在Web.config中定义的属性。这就提供了一个强类型的对象,可以在代码中使用它。同样,虽然每个使用用户配置的应用程序都具有一个ProfileCommon类,但是每个应用程序在应用程序的根命名空间下都有一个唯一的ProfileCommon类。因此在一个应用程序中的ProfileCommon类与另一个应用程序中的ProfileCommon类并不相同。
当用户请求一个页面时,ASP.NET使用用户配置提供程序来为该用户加载一个ProfileCommon类,而且这个对象就变成你可以在应用程序中各个页面内都可以访问到的Profile对象。接着你就可以在页面代码中使用Profile对象中的信息,并且设置合适的值。当页面完成处理后,ASP.NET使用用户配置提供程序来保存你在Profile对象中所做的任何修改,这样你就可以在随后用户的浏览中访问到这些信息了。ASP.NET完全是在后台处理用户配置信息的加载和保存,因此永远也不需要担心手动保存或加载任何东西。Profile对象根据配置设置来定义其属性。
启用和禁用用户配置
ASP.NET 2.0默认就启用用户配置,因此应用程序可以访问用户配置功能,除非你有意禁用用户配置。因为ASP.NET 2.0是基于每个请求来加载用户用户配置信息的,因此无论你是否在页面上使用到了用户配置信息,用户配置都会有一些开销的。所以,如果并不打算在应用程序中使用,那么就应该完全禁用用户配置。
所有的用户配置设置都位于Web.config中的<profile>配置节中。禁用用户配置设置是很简单的,你只需要在<profile>元素中把enabled属性设为false即可。
<system.web>
<profile enabled="false"></profile>
</system.web>
</configuration>
在禁用用户配置时,你无法在应用程序中访问Profile对象。任何对Profile对象的调用都会出错,而且应用程序无法编译。如果不在应用程序中使用它们,那么就应该禁用用户配置。
在Web.config中定义用户配置属性
通过在Web.config中<profiles>配置节内的<properties>元素中来定义Profile对象的属性,可以创建想要的属性,但是ASP.NET必须在每次请求时都把它们所有内容加载到Profile对象中,因此添加的属性越多,就要花更多的时间来加载。
PS: 如果你正在使用SqlProfileProvider(用户配置的默认提供程序),你可以从用户配置中添加和删除属性,而不会丢失现存属性的数据。如果你实现了自己的提供程序,或者使用第三方的提供程序,那么要小心你可能丢失数据,除非提供程序已经专门设计了完善地处理用户配置数据结构的修改。
定义了一个属性后,必须指定属性的name和type。作为可选项,可以使用defaultValue代码特性定义一个默认值。指定默认值是一个好方法,因为你可能需要在访问Web站点的用户收集到数据之前使用一个属性值。也可能定义对象属性类型,而不只是基本类型,只要这些类型是可序列化的。
实现用户配置属性类
并不需要在Web.config中定义所有用户配置属性。也可以在类中定义用户配置属性,从System.Web.Profile.ProfileBase类继承,在创建了自定义用户配置属性类后,必须配置ASP.NET使用这个自定义类,这是通过在<provider>元素中为inherits属性指定一个值来实现的。可以指定自定义属性类,并且仍在Web.config中定义属性。ASP.NET只是使用你自定义的类而不是ProfileBase来编译ProfileCommon类。ASP.NET使用ProfileBase或者是你在Web.config中指定的自定义类来编译ProfileCommon。
强类型属性
ASP.NET实际上会编译一个包含你的用户配置属性的类,因此,Profile对象公开了强类型的属性。这与Session对象完全不同,Session对象是以非强类型的键—值对来存储会话数据的。
ProfileManager类
System.Web.Profiles. ProfileManager类可以让你在应用程序中管理所有的用户配置。
1.ProfileInfo类
ProfileInfo对象是一个非常简单的类,存储了有关用户配置的基本信息。
2.ProfileAuthenticationOption枚举
在ProfileManager中的很多方法也使用ProfileAuthenticationOption枚举,让你基于用户配置是匿名的还是经过验证的来过滤结果。ProfileAuthenticationOption枚举包含3个值:All、Anonymous和Authenticated。
3.ProfileManager的属性和方法
FindInactiveProfilesByUserName、FindProfilesByUserName、GetAllInactiveProfiles和GetAllProfiles方法都包含重载,可以让你请求分页的数据
处理匿名用户配置
访问你的Web站点的用户要么是匿名用户,要么是通过了验证的用户,差别在于给用户配置增加了一定程度的复杂性。经过了验证的用户很容易识别,因为他们具有唯一的用户名,能在每次他们登录进来时识别他们。因此,ASP.NET可以轻松存储和跟踪验证过的用户的用户配置信息。另一方面,匿名用户并没有唯一用户名。这就会给存储和跟踪匿名用户的用户配置信息带来一点点麻烦。
不必做任何特殊的处理就能用经过了验证的用户的用户配置属性,因为ASP.NET知道用户的身份。然而,匿名用户需要一些特殊的处理。
启用匿名用户配置标识
ASP.NET是基于用户名来获取用户的用户配置信息。验证过了的用户,因为已经通过了验证,所以具有合法的、非空的、唯一的用户名,可以向Web站点表明他们的身份。每次一个通过验证的用户访问你的应用程序时,ASP.NET可以轻松地通过该用户的用户名获取该用户的用户配置信息。匿名用户并不包含唯一的用户名,但是ASP.NET仍需要一个唯一值,通过它来存储和获取匿名用户配置。ASP.NET使用匿名标识(anonymous identification)来绕开这个问题,这是一种为匿名用户分配一个唯一标识的机制。要实现这样的处理,匿名标识生成一个随机的唯一的ID,把唯一性ID保存到cookie中,然后把该cookie发送回该用户(或者与URL一起,取决于你的匿名标识配置)。
PS: 匿名标识与SessionID并不是相同的东西。基于cookie的匿名标识是持久性的,而且能跨多个浏览器会话持续识别匿名用户。基于URL的匿名用户识别只能在URL包含唯一性ID时才能生效。
每次匿名用户请求一个你的站点的页面时,该唯一标识符与请求跟在一起。接着ASP.NET使用该唯一标识符为该匿名用户获取合适的用户配置信息,即使他们没有被验证。ASP.NET使用自动生成的ID作为用户名存储用户配置信息,就像该匿名用户实际上是一个验证过了的用户一样。
在默认情况下,匿名标识并没有启用。要启用匿名标识,就把Web.config中<anonymousIdentification>配置节的enabled属性设为true。
<anonymousIdentification enabled="true"/>
</system.web>
什么时候使用匿名标识
当你想在用户通过验证之前跟踪用户的用户配置信息时,就应该使用匿名标识。因此,如果你希望用户在登录之前能访问你的Web站点的不同区域,那么你就应该考虑使用匿名标识在过渡时期来跟踪他们。
使用匿名标识最常见的情景之一就是针对购物车的应用程序。大多数顾客讨厌在购买产品之前被强制去创建一个账号,因此他们会在结账前保持匿名身份。在结账的过程中,他们要么需要使用现存的账号来登录,要么创建一个新的账号,此时他们才成为通过验证的用户。
ps: 当匿名用户登录进来并且变成一个通过了验证的用户时,匿名用户配置并不能自动转变成验证过的用户配置。ASP.NET获取该验证用户的用户配置(它可能是一个新的或现存的用户配置),而且在很短的时间内,该用户具有两个用户配置。ASP.NET接着就发出MigrateAnonymous事件,你可以在Global.asax中处理。这个事件可以让你从匿名用户配置转移任何设置到经过验证的用户配置。
匿名标识的缺点
在决定启用匿名标识之前,你要小心匿名标识可导致的一些副作用。大部分的副作用都是非常轻微的,但是在你知道它们是什么之后,你可以判断它们会对你的应用程序有多大的影响。
主要的副作用是ASP.NET所生成的唯一性ID很可能会丢失或者与匿名用户分离。匿名标识cookie的最佳场景是匿名用户总是从同一台服务器访问你的站点,而且永远不会清空cookie缓存。如果总是这样使用的话,那么匿名标识实际上就很完美了。不幸的是,用户总是喜欢从家里的计算机、办公室的计算机或者他们的朋友的计算机来访问你的站点。因此有些用户会定期删除cookie。其他用户完全禁用cookie。即使注册过的用户在他们真正登录进来之前也被认为是匿名用户。而且随着在机场、宾馆、咖啡店和图书馆提供计算机终端的趋势不断增加,你可能会面临匿名用户用户配置的问题。
1.准确性问题
匿名用户从多个地方登录到你的站点就会出现多个匿名用户配置,每个地方一个。因为每个用户配置都是被独立跟踪的,你就只能看到这个用户的部分信息。因此匿名用户配置的准确性就取决于用户总是使用同一台计算机,而且永远不会清空他们的cookie缓存。通过了验证的用户并不会有这样的问题,因为他们每次在登录时都是使用同一个用户配置。
2.分离的用户配置
在讨论精确性问题时,你看到了用户可以有多个活动的用户配置。匿名用户同样有可能会存在分离的用户配置。当标识cookie发送到浏览器时,它表示匿名用户和存储在数据库中的用户配置之间的唯一关联。如果该cookie丢失,那么在该用户和用户配置之间的关联就永远地消失了。用户配置仍在数据库中,但是不再会被访问到了。这就会导致硬盘控件的浪费。
3.硬盘空间的使用和性能
匿名标识最终会导致创建无关的用户配置记录。相应地,这就会浪费硬盘空间,并且强制你的数据库在查找相关的用户配置信息时检索过滤掉更多的“垃圾”。当你用ISP承载你的站点,这个ISP限制你的硬盘空间,那么硬盘空间问题就很值得注意,而当你在低配置硬件上运行应用程序,或者如果你试图支持大量用户时,性能问题就很值得注意。要不然,就不用考虑硬盘空间和性能问题。
PS:可以使ProfileManager对象来删除非活动的用户配置。
定义匿名用户配置属性
在默认情况下,用户配置属性并不允许匿名用户写入。试图写入会导致异常。如果你需要一个对匿名用户可写的属性,那么应该启用匿名标识,同时你必须特地在Web.config中标记该属性是一个匿名属性。
PS: 匿名用户配置属性这个短语看起来是表示该属性只用于匿名用户,但是情况并不是这样。匿名属性既可用于匿名用户也可以用于通过了验证的用户。它们的名称只是简单地标识匿名用户对该属性可写。
用IsAnonymous避免匿名写入异常
因为匿名用户只能写入匿名属性,所以你需要避免不小心针对匿名用户写入到非匿名属性。Profile对象的IsAnonymous属性返回一个Boolean值标识当前用户是否为匿名用户,因此你可以IsAnonymous属性用来区分非匿名用户配置属性。只要使用Profile.IsAnonymous隔离了非匿名用户配置属性,就永远不会遇到写入异常。
创建用户配置迁移代码
在处理匿名用户和验证用户时,匿名用户可能登录进来,并且成为验证用户。在出现这种情况时,ASP.NET就会发出MigrateAnonymous事件。在MigrateAnonymous事件中,存在两个用户配置:一个属于匿名用户,一个属于通过了验证的用户。这个事件可以让你有机会把用户配置值从匿名用户配置中复制到通过了验证的用户的用户配置中,这样它们就不会丢失了。
首先,你可能会想匿名用户配置应该重写通过了验证的用户配置,但是这可能会导致数据的丢失。一个匿名用户不需要表示一个以前从来没有访问过你的站点的用户。匿名用户可能是某个已经访问你的站点、有一个账号、而且具有用户配置、但是尚未登录的用户。比如,考虑一下购物车。一个现存用户可能会到你的Web站点并且开始购物。当用户去结账时,就要求他登录。当他登录后,他的匿名用户配置中就包含了所有购物车信息,而且他的验证过的用户配置中包含所有的个人信息。如果只是简单地重写通过了验证的用户配置,那么就可能会丢掉一些非常重要的信息。因此,你需要编写用户配置迁移代码把重要的数据从匿名用户配置中复制到通过了验证的用户配置中,而不需要重写通过了验证的用户配置中的现存数据。
当匿名用户验证时,就执行Global.asax中的Profile_MigrateAnonymous事件处理程序。你需要在这段程序中放置用户配置迁移代码。
2{
3
4 Profile.LastVisited=Profile.GetPropertyValue(e.AnonymousId).LastVisited;
5
6}
7
在这里用旧属性填充新的Profile属性。使用GetPropertyValue属性获取匿名用户的旧属性,该GetPropertyValue 属性把匿名用户的ID作为参数。在Profile_MigrateAnonymous事件中,仍可以访问AnonymousId属性,该属性从 ProfileMigrateEventArgs事件委托中获得。
除了迁移单个属性之外,还可以迁移个性化组中的属性。
在调用ASP.net页面时,ASP.NET创建了一个类 ProfileCommon,该类继承于ProfileBase类,用于强类型话在web.config文件中定义的profile属性。这个类可以处理 用户的配置文件存储,使用ProfileBase类中的GetPropertyValue和SetPropertyValue方法获取和设置 profile属性。
ASP.NET使用ProfileModule类提供了获取特定Profile事件所必需的关联。ASP.NET使用ProfileModule类在页面的Profile对象中创建和存储配置文件信息。
ProfileModule类有3个事件,可以用于处理用户的配置文件。这些事件分别是MigrateAnonymous,Personalize和ProfileAutoSaving,主要用于身份验证。