默认情况下,.Net网站上的MemberShip和Role功能只能用于SqlServer,如果要在其它数据库,比如Access,Oracle上使用该功能该怎么办呢?
其实MS早就为我们考虑到了,用户只要从MemberShipProvider和RoleProvider派生自己的Provider类,并实现相关的方法和属性就可以了,其实ASPX中的MemberShip功能就是这二个抽象类在SqlServer上的实现(有兴趣的朋友可以查阅一下System.Web.Security.SqlMembershipProvider)
这里只是给出一个MemberShip的演示,数据库结构如下:
用户表T_LoginUser
F_ID????????????用户ID
F_LoginName???? 登录名??
F_Password??????登录密码
自定义一个MyMemberShipProvider类,这里只实现了三个方法(Initialize,ValidateUser,CreateUser)
using?System;
using?System.Data;
using?System.Data.SqlClient;
using?System.Configuration;
using?System.Web;
using?System.Web.Security;
using?System.Web.UI;
using?System.Web.UI.WebControls;
using?System.Web.UI.WebControls.WebParts;
using?System.Web.UI.HtmlControls;
///?<summary>
///?MyMemberShipProvider?的摘要说明
///?</summary>
public?class?MyMemberShipProvider:System.Web.Security.MembershipProvider
{
????public?MyMemberShipProvider()
????{
????????//
????????//?TODO:?在此处添加构造函数逻辑
????????//
????}
????private?string?connStr;
????private?bool?_requiresQuestionAndAnswer;
????private?int?_minRequiredPasswordLength;
????public?override?int?MinRequiredPasswordLength
????{
????????get?{?return?_minRequiredPasswordLength;?}
????}
????public?override?bool?RequiresQuestionAndAnswer
????{
????????get
????????{
????????????return?_requiresQuestionAndAnswer;
????????}
????}
????///?<summary>
????///?初始化
????///?</summary>
????///?<param?name="name"></param>
????///?<param?name="config"></param>
????public?override?void?Initialize(string?name,?System.Collections.Specialized.NameValueCollection?config)
????{
????????if?(config["requiresQuestionAndAnswer"].ToLower()?==?"true")
????????{
????????????_requiresQuestionAndAnswer?=?true;
????????}
????????else
????????{
????????????_requiresQuestionAndAnswer?=?false;
????????}
????????int.TryParse?(config["minRequiredPasswordLength"],out?_minRequiredPasswordLength?);
????????connStr?=?config["connectionString"];
????????base.Initialize(name,?config);
????}
????///?<summary>
????///?验证用户
????///?</summary>
????///?<param?name="username"></param>
????///?<param?name="password"></param>
????///?<returns></returns>
????public?override?bool?ValidateUser(string?username,?string?password)
????{
????????using(SqlConnection?conn?=?new?SqlConnection(connStr))
????????{
????????????SqlCommand?comm?=?new?SqlCommand();
????????????comm.CommandText?=?"Select?Top?1?*?From?T_LoginUser?Where?F_LoginName=@LoginName?And?F_PassWord=@Password";
????????????comm.Parameters.AddWithValue("@LoginName",?username);
????????????comm.Parameters.AddWithValue("@Password",?password);
????????????comm.Connection?=?conn;
????????????conn.Open();
????????????using?(SqlDataReader?dr?=?comm.ExecuteReader())
????????????{
????????????????if?(dr.HasRows)
????????????????{???????????????????
???????????????????return?true;????????????????????
????????????????}
????????????????return?false;
????????????}
????????}????????
????}
????///?<summary>
????///?创建用户
????///?</summary>
????///?<param?name="username"></param>
????///?<param?name="password"></param>
????///?<param?name="email"></param>
????///?<param?name="passwordQuestion"></param>
????///?<param?name="passwordAnswer"></param>
????///?<param?name="isApproved"></param>
????///?<param?name="providerUserKey"></param>
????///?<param?name="status"></param>
????///?<returns></returns>
????public?override?MembershipUser?CreateUser(string?username,?string?password,?string?email,?string?passwordQuestion,?string?passwordAnswer,?bool?isApproved,?object?providerUserKey,?out?MembershipCreateStatus?status)
????{
????????using?(SqlConnection?conn?=?new?SqlConnection(connStr))
????????{
????????????SqlCommand?comm?=?new?SqlCommand();
????????????comm.CommandText?=?"Insert?Into?T_LoginUser(F_LoginName,F_Password)?values(@LoginName,@Password)";
????????????comm.Parameters.AddWithValue("LoginName",?username);
????????????comm.Parameters.AddWithValue("Password",?password);
????????????comm.Connection?=?conn;
????????????conn.Open();
????????????try
????????????{
????????????????comm.ExecuteNonQuery();
????????????}
????????????catch?(Exception?Ex)
????????????{
????????????????throw?new?Exception("创建用户失败!原因:"?+?Ex.Message.ToString());
????????????}
????????????MembershipUser?user?=?new?MembershipUser("MyMemberShipProvider",?username,?providerUserKey,?email,?passwordQuestion,?"",?isApproved,?true,?DateTime.Now,?DateTime.Now,?DateTime.Now,?DateTime.Now,?DateTime.Now);
????????????status?=?MembershipCreateStatus.Success;
????????????return?user;
????????}
????}
????public?override?string?ApplicationName
????{
????????get
????????{
????????????throw?new?Exception("暂未实现");
????????}
????????set
????????{
????????????throw?new?Exception("暂未实现");
????????}
????}
????public?override?bool?ChangePassword(string?username,?string?oldPassword,?string?newPassword)
????{
????????throw?new?Exception("暂未实现");
????}
????public?override?bool?ChangePasswordQuestionAndAnswer(string?username,?string?password,?string?newPasswordQuestion,?string?newPasswordAnswer)
????{
????????throw?new?Exception("暂未实现");
????}
???
????public?override?bool?DeleteUser(string?username,?bool?deleteAllRelatedData)
????{
????????throw?new?Exception("暂未实现");
????}
????public?override?bool?EnablePasswordReset
????{
????????get?{?throw?new?Exception("暂未实现");?}
????}
????public?override?bool?EnablePasswordRetrieval
????{
????????get?{?throw?new?Exception("暂未实现");?}
????}
????public?override?MembershipUserCollection?FindUsersByEmail(string?emailToMatch,?int?pageIndex,?int?pageSize,?out?int?totalRecords)
????{
????????throw?new?Exception("暂未实现");
????}
????public?override?MembershipUserCollection?FindUsersByName(string?usernameToMatch,?int?pageIndex,?int?pageSize,?out?int?totalRecords)
????{
????????throw?new?Exception("暂未实现");
????}
????public?override?MembershipUserCollection?GetAllUsers(int?pageIndex,?int?pageSize,?out?int?totalRecords)
????{
????????throw?new?Exception("暂未实现");
????}
????public?override?int?GetNumberOfUsersOnline()
????{
????????throw?new?Exception("暂未实现");
????}
????public?override?string?GetPassword(string?username,?string?answer)
????{
????????throw?new?Exception("暂未实现");
????}
????public?override?MembershipUser?GetUser(string?username,?bool?userIsOnline)
????{
????????throw?new?Exception("暂未实现");
????}
????public?override?MembershipUser?GetUser(object?providerUserKey,?bool?userIsOnline)
????{
????????throw?new?Exception("暂未实现");
????}
????public?override?string?GetUserNameByEmail(string?email)
????{
????????throw?new?Exception("暂未实现");
????}
????public?override?int?MaxInvalidPasswordAttempts
????{
????????get?{?throw?new?Exception("暂未实现");?}
????}
????public?override?int?MinRequiredNonAlphanumericCharacters
????{
????????get?{?throw?new?Exception("暂未实现");?}
????}
????public?override?int?PasswordAttemptWindow
????{
????????get?{?throw?new?Exception("暂未实现");?}
????}
????public?override?MembershipPasswordFormat?PasswordFormat
????{
????????get?{?throw?new?Exception("暂未实现");?}
????}
????public?override?string?PasswordStrengthRegularExpression
????{
????????get?{?throw?new?Exception("暂未实现");?}
????}
????public?override?bool?RequiresUniqueEmail
????{
????????get?{?throw?new?Exception("暂未实现");?}
????}
????public?override?string?ResetPassword(string?username,?string?answer)
????{
????????throw?new?Exception("暂未实现");
????}
????public?override?bool?UnlockUser(string?userName)
????{
????????throw?new?Exception("暂未实现");
????}
????public?override?void?UpdateUser(MembershipUser?user)
????{
????????throw?new?Exception("暂未实现");
????}
}
顺便也给个MyRoleProvider.cs,不过啥也没干,放了一个空架子,呵呵
using?System;
using?System.Data;
using?System.Configuration;
using?System.Web;
using?System.Web.Security;
using?System.Web.UI;
using?System.Web.UI.WebControls;
using?System.Web.UI.WebControls.WebParts;
using?System.Web.UI.HtmlControls;
///?<summary>
///?MyRoleProvider?的摘要说明
///?</summary>
public?class?MyRoleProvider:System.Web.Security.RoleProvider
{
????public?MyRoleProvider()
????{
????????//
????????//?TODO:?在此处添加构造函数逻辑
????????//
????}
????//?摘要:
????//?????获取或设置要存储和检索其角色信息的应用程序的名称。
????//
????//?返回结果:
????//?????要存储和检索其角色信息的应用程序的名称。
????public?override?string?ApplicationName?
????{
????????get?{?throw?new?Exception("暂未实现");?}
????????set?{?throw?new?Exception("暂未实现");?}
????}
????//?摘要:
????//?????将指定用户名添加到已配置的?applicationName?的指定角色名。
????//
????//?参数:
????//???roleNames:
????//?????一个字符串数组,其中包含要将指定用户名添加到的角色的名称。
????//
????//???usernames:
????//?????一个字符串数组,其中包含要添加到指定角色的用户名。
????public?override?void?AddUsersToRoles(string[]?usernames,?string[]?roleNames)?
????{
????????throw?new?Exception("暂未实现");
????}
????//
????//?摘要:
????//?????在数据源中为已配置的?applicationName?添加一个新角色。
????//
????//?参数:
????//???roleName:
????//?????要创建的角色的名称。
????public?override?void?CreateRole(string?roleName)?
????{
????????throw?new?Exception("暂未实现");
????}
????//
????//?摘要:
????//?????从数据源中移除已配置的?applicationName?的角色。
????//
????//?参数:
????//???throwOnPopulatedRole:
????//?????如果为?true,则在?roleName?具有一个或多个成员时引发异常,并且不删除?roleName。
????//
????//???roleName:
????//?????要删除的角色的名称。
????//
????//?返回结果:
????//?????如果成功删除角色,则为?true;否则为?false。
????public?override?bool?DeleteRole(string?roleName,?bool?throwOnPopulatedRole)?
????{
????????throw?new?Exception("暂未实现");
????}
????//
????//?摘要:
????//?????获取属于某个角色且与指定的用户名相匹配的用户名的数组。
????//
????//?参数:
????//???usernameToMatch:
????//?????要搜索的用户名。
????//
????//???roleName:
????//?????作为搜索范围的角色。
????//
????//?返回结果:
????//?????一个字符串数组,包含用户名与?usernameToMatch?匹配且用户是指定角色的成员的所有用户的名称。
????public?override?string[]?FindUsersInRole(string?roleName,?string?usernameToMatch)?
????{
????????throw?new?Exception("暂未实现");
????}
????//
????//?摘要:
????//?????获取已配置的?applicationName?的所有角色的列表。
????//
????//?返回结果:
????//?????一个字符串数组,包含在数据源中存储的已配置的?applicationName?的所有角色的名称。
????public?override?string[]?GetAllRoles()?
????{
????????throw?new?Exception("暂未实现");
????}
????//
????//?摘要:
????//?????获取指定用户对于已配置的?applicationName?所属于的角色的列表。
????//
????//?参数:
????//???username:
????//?????要为其返回角色列表的用户。
????//
????//?返回结果:
????//?????一个字符串数组,其中包含指定用户对于已配置的?applicationName?所属于的所有角色的名称。
????public?override?string[]?GetRolesForUser(string?username)?
????{
????????throw?new?Exception("暂未实现");
????}
????//
????//?摘要:
????//?????获取属于已配置的?applicationName?的指定角色的用户的列表。
????//
????//?参数:
????//???roleName:
????//?????一个角色名称,将获取该角色的用户列表。
????//
????//?返回结果:
????//?????一个字符串数组,其中包含属于已配置的?applicationName?的指定角色的成员的所有用户名。
????public?override?string[]?GetUsersInRole(string?roleName)?
????{
????????throw?new?Exception("暂未实现");
????}
????//
????//?摘要:
????//?????获取一个值,指示指定用户是否属于已配置的?applicationName?的指定角色。
????//
????//?参数:
????//???username:
????//?????要搜索的用户名。
????//
????//???roleName:
????//?????作为搜索范围的角色。
????//
????//?返回结果:
????//?????如果指定用户属于已配置的?applicationName?的指定角色,则为?true;否则为?false。
????public?override?bool?IsUserInRole(string?username,?string?roleName)?
????{
????????throw?new?Exception("暂未实现");
????}
????//
????//?摘要:
????//?????移除已配置的?applicationName?的指定角色中的指定用户名。
????//
????//?参数:
????//???roleNames:
????//?????一个字符串数组,其中包含要将指定用户名从中移除的角色的名称。
????//
????//???usernames:
????//?????一个字符串数组,其中包含要从指定角色中移除的用户名。
????public?override?void?RemoveUsersFromRoles(string[]?usernames,?string[]?roleNames)?
????{
????????throw?new?Exception("暂未实现");
????}
????//
????//?摘要:
????//?????获取一个值,该值指示指定角色名是否已存在于已配置的?applicationName?的角色数据源中。
????//
????//?参数:
????//???roleName:
????//?????要在数据源中搜索的角色的名称。
????//
????//?返回结果:
????//?????如果角色名已存在于已配置的?applicationName?的数据源中,则为?true;否则为?false。
????public?override?bool?RoleExists(string?roleName)?
????{
????????throw?new?Exception("暂未实现");
????}
}
下面是关键的Web。config配置
<?xml?version="1.0"?>
<configuration>
????<appSettings/>
????<connectionStrings>
????????<add?name="connStr"?connectionString="Data?Source=.\SQLEXPRESS;AttachDbFilename=|DataDirectory|\demo.mdf;Integrated?Security=True;User?Instance=True"?providerName="System.Data.SqlClient"/>
????</connectionStrings>
????<system.web>
????????
????????<compilation?debug="true"/>
????????
????<authentication?mode="Forms">
??????<forms?defaultUrl="~/Default.aspx"?name="MemberShipProviderDemo"?cookieless="UseCookies"></forms>
????</authentication>
????
????
????
????????<membership?defaultProvider="MyMemberShipProvider">
????????????<providers>
????????????????<add?type="MyMemberShipProvider"?name="MyMemberShipProvider"?requiresQuestionAndAnswer="false"?connectionString="Data?Source=.\SQLEXPRESS;AttachDbFilename=|DataDirectory|\demo.mdf;Integrated?Security=True;User?Instance=True"/>
????????????</providers>
????????</membership>???
????
????
????</system.web>
</configuration>
好了,随便建一个Default.aspx,放一个Login控件和CreateUserWizard控件就可以测试了