1.1.1 成员身份服务
ASP.NET 2.0中新增的最佳功能之一就是成员身份服务,属于ASP.NET提供程序模型的基础结构之一。所以有必要了解一下ASP.NET提供程序模型,它是ASP.NET 2.0推出的最有吸引力的特征之一,基于通用的面向对象方式(继承,多态),并可以实现无限扩展。其本身也应用了几个典型的设计模式(策略模式、适配器模式、工厂模式)。虽然ASP.NET和Microsoft Windows Forms都依赖于提供程序,但是它们不属于相同的领域,前者在成员资格和个性化等关键服务中采用了提供程序模型,后者则仅用该模型存储用户和应用程序设置,本节后面会加以更多的阐述。对于成员身份服务,它提供了用于创建和管理用户账户的易于使用的API。除了用户的凭据验证和管理,还提供了有关密码的高级服务,可以自由定制密码的最小长度,必须满足大小写标点的格式,同时还提供启用或禁用密码的检索服务,将其绑定到问答模式上来。读者应该知道在ASP.NET 1.x中大规模引入了窗体身份验证,但仍然要求你编写相当数量的代码来执行实际操作中的窗体身份验证。成员身份服务填补了ASP.NET 1.x窗体身份验证服务的不足,并且使实现窗体身份验证变得比以前简单得多。
成员身份API通过两个新的类来实现:Membership和MembershipUser,它们是一对配合得很好的搭档。前者包含了用于创建用户、验证用户以及完成其他工作(找回一个membershipUser实例,更新一个membershipUser实例,通过不同条件寻找一个用户,获得当前在线用户数量,删除一个已经不再需要的账户)的静态方法。MembershipUser代表单个用户,它包含了用于检索和更改密码、获取上次登录日期以及完成类似工作的方法和属性。
下面以一个具体的例子来阐述Membership的使用方法:本例以Membership的CreateUser方法创建一个用户。
首先要配置数据库以方便我们把数据存储在里面,以Windows XP SP2操作系统和SQL Server 2000数据库为例。
① 注册数据库
打开:C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\aspnet regsql.exe请根据您自己的系统选择相应路径,如图1-1所示。
图1-1
② 单击“下一步”按钮,选择要执行的数据库任务,如图1-2所示。
图1-2
③ 单击“下一步”按钮,选择服务器和数据库,如图1-3所示。
图1-3
④ 单击“下一步”按钮,确认注册信息正确,如图1-4所示。
图1-4
⑤ 这一步骤完成后,ASP.NET将会在你设置的数据库中生成相应的表和一些存储过程,如图1-5所示。
图1-5
⑥ 到这一步数据库的注册已经完成,接下来要做的就是更改IIS中的配置选项,打开默认网站的属性控制面板,查看ASP.NET选项卡,如图1-6所示。
图1-6
⑦ 编辑配置并编辑数据库连接字符串,连接到上面设置的数据库上,如图1-7所示。
图1-7
⑧ 在新建的项目文件页面中定义如图1-8所示的表格。
图1-8
⑨创建用户事件,代码如下:
protected void btnCreate_Click(object sender, EventArgs e) { string userName = txtUserId.Text.Trim(); string pwd = txtPassword.Text.Trim(); string email = txtEmail.Text.Trim(); string question = ddlQuestion.SelectedValue.ToString(); string answer = txtAnswer.Text.Trim(); MembershipCreateStatus status; Membership.CreateUser(userName, pwd, email, question, answer, true, out status); switch (status) { case MembershipCreateStatus.Success: Response.Write("操作成功"); break; default: Response.Write("操作失败"); break; } }
至此一个Membership的简单例子演示完毕。有开发经验的读者可能已经发现问题的所在了,由于框架本身提供的功能有限。如Membership的CreateUser方法只提供了三个重载方法,在创建一个用户时可能需要获取用户的更多信息,如姓名、性别、地址、职称等。还有上面的数据库是SQL Server2000而不是默认的SQL Server 2005 Express数据库,怎么办?这时我们可以采用前面讨论的特性来解决:提供程序模型。与上面问题有关的是MembershipProvider。提供程序模型中还包括很多其他提供程序:PersonalizationProvider、ProfileProvider、RoleProvider、SiteMapProvider、WebEventProvider等。
提供程序模型的概念建立在继承ProviderBase类的基础之上,ProviderBase类是System.Configuration程序集的System.Configuration.Provider命名空间中的新类,它是一个抽象类,对于ASP.NET 2.0支持的任何服务,所有提供程序都会派生自这样一个公共基类,为提供程序的实现者继承。这个类非常简单,只提供了几个在大多数提供程序中都有用的方法和属性,如表1-1所示。
表1-1 提供程序类
提供程序类的层次结构图如图1-9所示。
图1-9
了解了上面的知识,我们就可以从扩展内置的提供程序入手来实现那些不能很好满足我们需求的功能了。最简单的一种方法是继承一个内置的实现方式,例如SqlMembership Provider。这么做有几个原因,但这里要说明的是如何验证当前登录的特定用户。为此,我们将继承一个内置提供程序,重写ValidateUser方法,来实现时间限制功能。
首先需要创建一个类,使它继承已有的SqlMembershipProvider,所在的命名空间为System. Web.Security.SqlMembershipProvider;然后在配置文件中配置新的提供程序,把defaultProvider的值改为以继承为SqlMembershipProvider类的名称;其次是检查提供程序的配置,以确保程序的正确性。打开Web Site Administration Tool(选择Visual Studio 2005 WebSite菜单,再选择ASP.NET Configuration选项),进入Provider选项卡,就会发现,新建的提供程序现在已经是一个可选的成员提供程序。最后就是对我们的方法进行重写了。
public override bool ValidateUser(string username,string password) { if((username!="kim")&&(password!="P@ssw0rd123 ")) return false; return base.ValidateUser(username, password); }
当然我们还可以直接建立自己的成员提供程序,来实现一个定制类,以履行提供程序的契约。这么做的一个主要原因是,例如,成员提供程序默认为ASP.NET成员服务的一个接口,它把数据存储在数据库的专用ASP.NET表中,许多已有的应用程序都有成员表的概念,而替换它们来利用某些使用成员提供程序的内置控件,其工作量很大。但是,当我们创建一个执行MembershipProvider类的重要方法的类时,就可以让定制类对已有的数据库执行成员操作。这类定制并不限于对数据库执行操作,还可以从定制类中调用第三方供应商的API。实现方式很简单,直接继承MembershipProvider类即可,具体实现思路和上面的例子一样。
虽然这是一些相当简单的例子,但却说明了如何利用内置提供程序来满足应用程序需要的附加业务要求,同时不需要重新实现已提供的全部功能。