如何微调会员提供商?

时间:2010-04-30 16:38:23

标签: .net asp.net asp.net-membership membership-provider custom-membershipprovider

在我上次question about fine-tuning的所有答案都比我预期的更有用之后,我想我也会问另一个关于会员提供者的类似问题。

好的,首先,澄清一下:我知道成员资格,角色和资料提供者是什么,如何实现我自己,以及如何配置它们,以及它们的大部分内容。
实现角色和配置文件提供程序非常简单,因为它们大多数时候只需要简单的CRUD。 (对于大约一半的RoleProvider方法,单行LINQ就足够了。)

然而,会员提供者是一个不同的野兽。你们中的许多人可能会意识到它违反了SR(单一责任)原则,因为它必须做与用户管理相关的一切。虽然这为自定义留下了很大的空间,但它也有其缺点。 互联网上没有关于他们的EXACT预期行为的信息,例如他们何时应该抛出异常或只是返回null,以及类似的东西。

我使用this sample implementation作为参考,但它也包含几个矛盾。

  • 例如,它使用自己的ValidateUser方法检查ChangePassword方法中的凭据。但ValidateUser还会将用户的LastLoginDate更新为当前日期。那么,框架是否期望我在我自己的提供者中设置它,或者它只是样本中的错误?
  • 另一个是:每次验证新密码时,ChangePassword方法都会引发异常,但CreateUser不会抛出异常,它只返回false。
  • 最后,但并非最不重要:它计算用户的无效密码尝试,并在超过阈值时锁定它们。虽然这很好,但它需要手动操作来解锁用户。如果我的提供商在一段时间后自动解锁用户,会出现问题吗?

  • (编辑)我差点忘了:示例中的CreateUser方法插入方法参数中的ID。我实际上认为这是不好的做法,因为我使用自动插入作为ID,因此从一些方法参数插入它们不是一个选项。我应该忽略参数,还是要求它的值为null,如果不是则抛出异常?

总而言之,ASP.NET是否对MembershipProvider的行为有任何假设? 是否有任何文档描述何时应该抛出异常或只返回null?

我还试图找到一组通用的单元测试,这些测试可以提供有关预期行为的一些指导,但没有运气,我发现大量关于“单元测试很好”的文章,以及“如何对MembershipProvider进行单元测试” ,但不会有任何实际测试。

先谢谢大家!

1 个答案:

答案 0 :(得分:4)

您可以咨询MSDN以获取指导。例如,RoleProvider.RemoveUsersFromRoles提供以下指导:

  

RemoveUsersFromRoles被调用   RemoveUserFromRole,   RemoveUsersFromRole,   RemoveUserFromRoles,和   RemoveUsersFromRoles方法了   Roles类删除指定的   来自指定角色的用户   数据源。只有角色   配置的ApplicationName是   修改。

     

如果有任何指定的角色名称   找不到配置的   applicationName,我们建议   你的提供者抛出一个   ProviderException。

     

如果有任何指定的用户名   与任何一个没有关联   指定的角色名称   配置的applicationName,我们   建议你的提供者抛出一个   ProviderException。

     

如果有任何指定的用户名   null或是一个空字符串,我们   建议你的提供者扔一个   异常。

     

如果有任何指定的角色名称   null或是一个空字符串,我们   建议你的提供者扔一个   异常。

     

如果您的数据源支持   交易,我们建议您   包括每个删除操作   交易和你回滚   如果是事务并抛出异常   任何删除操作都会失败。

RoleProvider.GetRolesForUser说:

  

GetRolesForUser由Roles类的GetRolesForUser方法调用,以从数据源检索指定用户与之关联的角色名称。仅检索已配置的ApplicationName的角色。

     

如果指定用户没有为配置的applicationName存在任何角色,我们建议您的提供程序返回不带元素的字符串数组。

     

如果指定的用户名为null或为空字符串,我们建议您的提供者抛出异常。

但是,实际上,每个提供商中只有一些方法和行为是必需的和预期的。其余部分支持您希望实现的功能。

经过几年处理默认提供程序堆栈后,我逐渐了解了一些让您暂停链接的示例,这是一个非常简单的实现,例如,在ChangePassword中削减角落方法

如果你使用反射器并检查SqlMembershipProvider,你会发现一些显着的差异......

例如:

  • ValidateUser更新登录日期,因为用户正在登录,并且通过调用.CheckPassword为true来实现UpdateLastLoginTime。更改密码调用相同的方法,但提供错误。

  • CreateUser方法接受ProviderUserKey,因为SPROC也将接受UserId参数。这是为了允许成员资格和用户表之间的娱乐和同步。作为API的使用者,您通常不会使用此功能,但提供程序堆栈在内部使用。

  • 关于停工......这取决于你。这就是实现自定义提供程序的关键所在:获得所需的行为。正如我所说,系统要求很少。

因此,这将我们带到你问题的最后部分(两个段落都提到了相同的问题):预期的行为和单元测试......

由于提供者的行为在很大程度上是任意的并且预期行为很少,因此一组既定的通用测试将包含非常少的方法。您需要编写适用于实现行为的测试。

最后请注意,我建议您finddownload使用Asp.Net提供程序工具包示例。它为您提供了完整的Sql提供程序堆栈的工作源代码,并将为您提供有关如何实现“真实”提供程序的一些信息。

<强>后记

此时此刻,我正在实现一个与默认Sql堆栈100%兼容的完整SQLite提供程序堆栈。测试套件验证我的堆栈和asp.net之间的行为平等。如果您通过我的个人资料访问我的博客并与我联系,我会在测试完成后通知您,您可以将它们用作默认堆栈预期的基准。