用户配置模型可以很好的嵌入 ASP.NET 网页。但是它的可配置性并不是非常好。你可能需要创建一个自定义的用户配置提供程序,原因如下:
- 需要将用户配置信息存储在其他类型的数据库里。比如,Oracle。
- 希望用户配置数据对其他程序也是有效的。分析 PropertyValuesString 和 PropertyValuesBinary 字段中的信息枯燥且易出错,如果要在其他程序或查询中获取信息,存储在一个字段彼此独立的表中会是一个很好的方案。
- 当保存或获取用户配置数据时,需要实现一些额外的逻辑。比如,验证、缓存、记录、加密或者压缩。
1. 自定义的用户配置提供程序类
为了实现自定义用户配置提供程序,需要继承 System.Web.Profile 命名空间的 ProfileProvider 抽象类;ProfileProvider 类又继承自 System.Configuration 命名空间的 SettingsProvider 抽象类;而 SettingsProvider 类则从 System.Configuration.Provider 命名空间的 ProviderBase 抽象类集成二来。基于此,你需要实现 SettingsProvider 类和 ProviderBase 类的成员。总的来讲,有一大堆的成员需要实现,之后才可以编写自定义的用户配置提供程序。
但是,这些方法并不是同等重要的。比如,你可以创建一个基本的提供程序,它通过实现 2 个或者 3 个这样的方法来保存和获取用户配置信息。其他许多方法提供了 ProfileManager 类的一些功能,比如删除用户配置或搜索不活动的用户配置。
所有这些方法都是非常容易实现的(仅仅需要一些基本的 ADO.NET 代码),但是,正确的实现每一个方法需要相当数量的代码。
用户配置提供程序的抽象成员
| 类 | 成 员 | 描 述 |
| *ProviderBase | Name | 只读属性,返回当前提供程序的名称(在 web.config 中设置) |
| *ProviderBase | Initialize() | 从 web.config 中获得配置元素,这些元素初始化了这个提供程序。这个方法给了你一个机会来读取自定义的设置,并将这些信息存储在成员变量中 |
| *SettingsProvider | ApplicationName | 程序名(在 web.config 中设置),允许你区分存储在同一个数据库中的不同程序的用户 |
| *SettingsProvider | GetPropertyValues() | 为一个单独用户获取用户配置信息。当一个网页访问 Page.Profile 属性时,这个方法会自动被调用。该方法可得到程序中定义的所有用户配置属性的列表,你必需为每个属性都返回一个值 |
| *SettingsProvider | SetPropertyValues() | 更新一个用户的用户配置信息。当用户配置信息被修改后,在页面请求结束的时候这个方法会自动被调用。 |
| ProfileProvider | DeleteProfiles() | 删除一个或多个用户的用户配置记录 |
| ProfileProvider | DeleteInactiveProfiles() | 删除指定时间以来未被访问过的用户配置记录 |
| ProfileProvider | GetAllProfiles() | 返回一组用户配置记录的信息。这个方法必须支持分页功能。 |
| ProfileProvider | GetAllInactiveProfiles() | 查找指定时间以来未被访问过的用户配置记录 |
| ProfileProvider | FindProfilesByUserName() | 基于一个或多个(如果你支持通配符匹配)用户名获取用户配置信息。但实际的用户配置信息不会被返回,只有一些标准的信息,比如最后活动时间等会被返回 |
| ProfileProvider | FindInactiveProfilesByUserName() | 和上面类似,但以指定时间为基准进行查找 |
| ProfileProvider | GetNumberOfInactiveProfiles() | 计算自从指定时间以来没有被访问过的记录个数 |
2. 设计 FactoredProfileProvider
FactoredProfileProvider 将属性值存储在一个数据库表中的一些列字段中,而不是一个单独的数据块中。这样其他程序和在不同查询中使用这些值就非常容易了。
从本质上讲,FactoredProfileProvider 解锁了用户配置表格,这样它就不再使用一个专有的模式了。唯一的缺点是,如果不修改数据库模式,你就不能修改用户配置或者将信息添加到用户配置中。
当实现一个自定义的用户配置程序时,你需要决定解决方案的通用性。比如,你决定使用 System.IO.Compression 命名空间中的类来实现压缩;或者使用 System.Security.Cryptography 命名空间中的类来实现加密。
FactoredProfileProvider 的基本思想是通过两个存储过程实现两个比较关键的功能(获取和更新用户配置信息)。这就带来了很大的灵活性,因为你可以在任何时候通过修改存储过程来使用不同的表、字段名、数据类型乃至序列化方式。
下面是在应用程序中使用 FactoredProfileProvider 的例子:
<providers>
<clear />
<add name="FactoredProfileProvider" type="FactoredProfileProvider" connectionStringName="SqlServices"
updateUserProcedure="Users_Update" getUserProcedure="Users_GetByUserName"/>
</providers>
<properties>
...
</properties>
</profile>