ASP.NET Provider模型

在本系列的第一和 第二部分,我们介绍了 ASP.NET Provider 的概念和内部体系结构,我们知道 provider 模型是可以扩展的,我们可以自己定义自己的模型结构来完成更适合自己需求的 Provider 。本文将自定义自己的两个 Providers-- 一个是成员 membership Provider ,另外一个是角色 Role Provider
 
为什么开发自定义 Membership Role Provider
怎么说呢,原因可能很多,下面列出了部分原因:
你使用了其它数据库(也就是不是 SQL Server 或者 Access 数据库)来存放你的数据
你使用了一些非标准的数据库而这些数据库并没有内置的 membership role Providers 模型
你想要执行数据在包含和检索过程具有加密的功能
你想要自己写数据库的处理而非以来于 membership role  Provider 模型
 
需求
现在让我们决定自定的 membership role Provider 需要什么要求:
我们想要使用我们自己的数据库来存放 membership role 信息,这就意味者我们不需要使用中间数据存储应用程序的名称
我们使用自定义的 Users 表来存放成员关系的详细信息
我们使用自定义的 Roles 表存放系统里可以使用的角色
我们使用 UserRoles 表来映射 User-Role 的关联
 
为了简化本示例,我们不再提供如下功能
密码的“加密 - 解密”功能
用户注册时主要输入用户名,密码和邮件即可,不用输入安全提问和答案
我们不需要诸如密码恢复,账号锁定等功能
 
数据访问
  这里我们使用 BinaryIntellect DatabaseHelper  来完成本模块的数据库访问
 
建立 Web 站点
   首先,建立一个 Web 站点,然后在 App_Code 目录学建立两个类: MyMembershipProvider  MyRoleProvider 。为了简化应用程序,我们建立 webSite 本身需要的必要类。在实际的应用中,你可以建立单独的类来包含这些类。
 
配置 Web 应用程序使用自定义 Providers
  打开 web.config 并增加如下的标记:
 
<membership defaultProvider="mymembershipprovider">
<providers>
<add name="mymembershipprovider" 
type="MyMembershipProvider" 
connectionStringName="connstr"/>
</providers>
</membership> 
 
 
<roleManager enabled="true" defaultProvider="myrolesprovider"> 
<providers> 
<add name="myrolesprovider" 
type="MyRolesProvider" 
connectionStringName="connstr"/> 
</providers>
</roleManager>
 
在这两段代码里,我们告诉 ASP.NET 系统使用 MyMembershipProvider 类来作为成员关系的提供者,使用 MyRolesProvider 类来作为角色的提供者,建立自定义成员关系的 Provider
回忆一下第二部分介绍的程序关系 Provider 模型,我们需要从 System.Web.Security.MembershipProvider  类派生出自定义的成员类
MembershipProvider 类又是从 ProviderBase 类继承而来。 MembershipProvider 类包含几个抽象的方法,你可以在你自定义的类中使用这些方法
如果你使用的是 VS.NET 开发环境,那么你可以减轻开发的工作。在 MembershipProvider 类的定义处右击属性,转到 MembershipProvider 类的定义可以看到其属性 / 方法
 
下面列出了改类属性 / 方法以及意义的列表
(天天注:  这里的意义翻译并没有取之原文,因为中文版本的 MSDN 已经提供了,你可以查看 Member Provider 类的成员列表)

属性 / 方法
意义
Initialize()*
初始化提供程序。在这里获取 web.config 里数据库链接字符串的值,我们需要在自己的类里进行数据库处理
Name*
这里程序自定义 Provider 的名称。
CreateUser()*
建立一个用户
UpdateUser()*
保护注册用户资料的更改
DeleteUser()*
删除一个用户
GetUser()*
获取一个 MembershipUser 对象实例
GetAllUsers()*
获取 MembershipUserCollection 里用户的集合
ChangePassword()*
更改密码
GetPassword()*
从数据源获取指定用户名所对应的密码。
ValidateUser()*
验证数据源中是否存在指定的用户名和密码。
EnablePasswordReset*
指示成员资格提供程序是否配置为允许用户重置其密码。
EnablePasswordRetrieval*
指示成员资格提供程序是否配置为允许用户检索其密码。
RequiresQuestionAndAnswer*
获取一个值,该值指示成员资格提供程序是否配置为要求用户在进行密码重置和检索时回答密码提示问题。
RequiresUniqueEmail*
获取一个值,指示成员资格提供程序是否配置为要求每个用户名具有唯一的电子邮件地址。
ApplicationName
使用自定义成员资格提供程序的应用程序的名称。
MaxInvalidPasswordAttempts
获取锁定成员资格用户前允许的无效密码或无效密码提示问题答案尝试次数。
MinRequiredNonAlphanumericCharacters
获取有效密码中必须包含的最少特殊字符数。
MinRequiredPasswordLength
获取密码所要求的最小长度。
ChangePasswordQuestionAndAnswer()
处理更新成员资格用户的密码提示问题和答案的请求。
FindUsersByEmail()
获取一个成员资格用户的集合,这些用户的电子邮件地址包含要匹配的指定电子邮件地址。
FindUsersByName()
获取一个成员资格用户的集合,这些用户的用户名包含要匹配的指定用户名。
GetNumberOfUsersOnline()
获取当前访问该应用程序的用户数。
GetUser()
从数据源获取成员资格用户的信息。
GetUserNameByEmail()
利用邮件获取用户名
PasswordAttemptWindow
指示密码输入间隔的时间
PasswordFormat
密码格式,例如明文, Hash 表等
PasswordStrengthRegularExpression
密码使用的正则表达式
ResetPassword()
重置用户密码
UnlockUser()
接锁用户

 
在我们的代码里,我们将重载上面列出的前面具有“ * ”标记的属性或者方法,其它的属性方法只简单的抛出一个“没有执行”的异常
完整的源代码请见下载文件里的 MyMembershipProvider.cs ,部分代码如下
(天天注:这里引用了更多的源代码)
 
using BinaryIntellect.DataAccess;
 
public class MyMembershipProvider:MembershipProvider
{
    private DatabaseHelper db = null;
public override void Initialize(string name, System.Collections.Specialized.NameValueCollection config)
    {
string connstr = ConfigurationManager.ConnectionStrings[config["connectionStringName"]].ConnectionString;
        db = new DatabaseHelper(connstr);
    }
 
    public override string Name
    {    get {  return "MyMembershipProvider";     }
    }
 
    public override MembershipUser CreateUser(string username, string password, string email, string passwordQuestion, string passwordAnswer, bool isApproved, object providerUserKey, out MembershipCreateStatus status)
    {
        MembershipUser user = new MembershipUser(Name, username, providerUserKey, email, passwordQuestion, null, isApproved, false, DateTime.Now, DateTime.Now, DateTime.Now, DateTime.Now, DateTime.Now);
        string sql = "INSERT INTO USERS(USERNAME,PASSWORD,EMAIL,ISACTIVE) VALUES(@UID,@PWD,@EMAIL,@ISACTIVE)";
        db.AddParameter("@UID", username);
        db.AddParameter("@PWD", password);
        db.AddParameter("@EMAIL", email);
        db.AddParameter("@ISACTIVE", (isApproved == true ? "Y" : "N"));
        int i = db.ExecuteNonQuery(sql);
 
        if (i > 0)
        {
            status = MembershipCreateStatus.Success;
            return user;
        }
        else
        {
            status = MembershipCreateStatus.ProviderError;
            return null;
        }
 
    }
 
    public override void UpdateUser(MembershipUser user)
    {
        string sql = "UPDATE USERS SET EMAIL=@EMAIL,ISACTIVE=@ISACTIVE WHERE USERNAME=@UID";
        db.AddParameter("@EMAIL", user.Email);
        db.AddParameter("@ISACTIVE", (user.IsApproved ? "Y" : "N"));
        db.AddParameter("@UID", user.UserName);
        int i = db.ExecuteNonQuery(sql);
    }
 
    public override bool DeleteUser(string username, bool deleteAllRelatedData)
    {
        string sql = "DELETE FROM USERS WHERE USERNAME=@UID";
        db.AddParameter("@UID", username);
        int i = db.ExecuteNonQuery(sql);
        if (i > 0)
            return true;
        else
            return false;
 
    }
 
    public override MembershipUser GetUser(string username, bool userIsOnline)
    {
        MembershipUser user = null;
        string sql = "SELECT * FROM USERS WHERE USERNAME=@UID AND ISACTIVE='Y'";
        db.AddParameter("@UID", username);
        SqlDataReader reader = (SqlDataReader)db.ExecuteReader(sql);
        while (reader.Read())
        {
            user = new MembershipUser(Name, reader.GetString(reader.GetOrdinal("username")), null, reader.GetString(reader.GetOrdinal("email")), null, null, (reader.GetString(reader.GetOrdinal("isactive")) == "Y" ? true : false), false, DateTime.MinValue, DateTime.MinValue, DateTime.MinValue, DateTime.MinValue, DateTime.MinValue);
        }
        reader.Close();
        return user;
    }
 
    public override MembershipUserCollection GetAllUsers(int pageIndex, int pageSize, out int totalRecords)
    {
        MembershipUserCollection users = new MembershipUserCollection();
        object obj=db.ExecuteScalar("SELECT COUNT(*) FROM USERS");
        int reccount=0;
        if (obj != null)
            reccount = (int)obj;
        SqlDataReader reader = (SqlDataReader)db.ExecuteReader("SELECT * FROM USERS ORDER BY USERNAME");
        while (reader.Read())
        {
            MembershipUser user = new MembershipUser(Name, reader.GetString(reader.GetOrdinal("username")), null, reader.GetString(reader.GetOrdinal("email")), null, null, (reader.GetString(reader.GetOrdinal("isactive")) == "Y" ? true : false), false, DateTime.MinValue, DateTime.MinValue, DateTime.MinValue, DateTime.MinValue, DateTime.MinValue);
            users.Add(user);
        }
        reader.Close();
        totalRecords = reccount;
        return users;
    }
 
    #endregion
 
    #region Password Management
 
    public override bool ChangePassword(string username, string oldPassword, string newPassword)
    {
        string sql = "UPDATE USERS SET PASSWORD=@NEWPWD WHERE USERNAME=@UID AND PASSWORD=@OLDPWD";
        db.AddParameter("@NEWPWD", newPassword);
        db.AddParameter("@UID", username);
        db.AddParameter("@OLDPWD", oldPassword);
        int i = db.ExecuteNonQuery(sql);
        if (i > 0)
            return true;
        else
            return false;
    }
 
    public override string GetPassword(string username, string answer)
    {
        string sql = "SELECT PASSWORD FROM USERS WHERE USERNAME=@UID";
        db.AddParameter("@UID", username);
        object obj = db.ExecuteScalar(sql);
        if (obj != null)
            return obj.ToString();
        else
            return "";
    }
    #endregion
 
    #region Authentication
 
    public override bool ValidateUser(string username, string password)
    {
        string sql = "SELECT USERNAME FROM USERS WHERE USERNAME=@UID AND PASSWORD=@PWD";
        db.AddParameter("@PWD", password);
        db.AddParameter("@UID", username);
        string uid = db.ExecuteScalar(sql) as string;
        if (uid == null)
        {
            return false;
        }
        else
        {
            return true;
        }
    }
    #endregion
 
    #region Provider Configuration
 
    public override bool EnablePasswordReset
    {
        get
        {
            return false;
        }
    }
 
    public override bool EnablePasswordRetrieval
    {
        get 
        {
            return true;
        }
    }
 
    public override bool RequiresQuestionAndAnswer
    {
        get
        {
            return false;
        }
    }
 
    public override bool RequiresUniqueEmail
    {
        get
        {
            return false;
        }
    }
    #endregion
 
}
 
建立自定义的角色 Provider
 该类完成列表请参考MSDN:RoleProvider

属性 / 方法
意义
Initialize()*
初始化提供程序。
Name*
显示自定义 Provider 的名称
CreateRole*
在数据源中为已配置的  applicationName  添加一个新角色。
DeleteRole*
从数据源中移除已配置的  applicationName  的角色。
GetAllRoles*
获取已配置的  applicationName  的所有角色的列表。
RoleExists*
获取一个值,该值指示指定角色名是否已存在于已配置的  applicationName  的角色数据源中。
AddUsersToRoles*
将指定用户名添加到已配置的  applicationName  的指定角色名。
RemoveUsersFromRoles*
移除已配置的  applicationName  的指定角色中的指定用户名。
GetRolesForUser*
获取指定用户对于已配置的  applicationName  所属于的角色的列表。
GetUsersInRole*
获取属于已配置的  applicationName  的指定角色的用户的列表。
IsUserInRole*
获取一个值,指示指定用户是否属于已配置的  applicationName  的指定角色。
ApplicationName
获取或设置要存储和检索其角色信息的应用程序的名称。
FindUsersInRole
获取属于某个角色且与指定的用户名相匹配的用户名的数组。

在我们的代码里,我们将重载上面列出的前面具有“ * ”标记的属性或者方法,其它的属性方法只简单的抛出一个“没有执行”的异常
下面列出了部分代码
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;
using BinaryIntellect.DataAccess;
using System.Collections;
 
public class MyRolesProvider:RoleProvider
{
    private DatabaseHelper db = null;
 
    #region General
 
    public override void Initialize(string name, System.Collections.Specialized.NameValueCollection config)
    {
        string connstr = ConfigurationManager.ConnectionStrings[config["connectionStringName"]].ConnectionString;
        db = new DatabaseHelper(connstr);
    }
 
    public override string Name
    {
        get
        {
            return "MyRolesProvider";
        }
    }
    #endregion
 
    #region Role Management
 
    public override void CreateRole(string roleName)
    {
        db.AddParameter("@ROLE", roleName);
        db.ExecuteNonQuery("INSERT INTO ROLES(ROLENAME) VALUES(@ROLE)");
    }
 
    public override bool DeleteRole(string roleName, bool throwOnPopulatedRole)
    {
        db.AddParameter("@ROLE", roleName);
        int i = db.ExecuteNonQuery("DELETE FROM ROLES WHERE ROLENAME=@ROLE");
        if (i > 0)
            return true;
        else
            return false;
    }
 
    public override string[] GetAllRoles()
    {
        int reccount = (int)db.ExecuteScalar("SELECT COUNT(*) FROM ROLES");
        SqlDataReader reader = (SqlDataReader)db.ExecuteReader("SELECT ROLENAME FROM ROLES");
        string[] roles = new string[reccount];
        int i = 0;
        while (reader.Read())
        {
            roles[i] = reader.GetString(0);
            i++;
        }
        reader.Close();
        return roles;
    }
 
    public override bool RoleExists(string roleName)
    {
        db.AddParameter("@RID", roleName);
        object obj = db.ExecuteScalar("SELECT ROLENAME FROM ROLES WHERE ROLENAME=@RID");
        if (obj != null)
        {
            return true;
        }
        else
        {
            return false;
        }
 
    }
 
    #endregion
 
    #region Users and Roles
 
    public override void AddUsersToRoles(string[] usernames, string[] roleNames)
    {
        foreach (string user in usernames)
        {
            foreach (string role in roleNames)
            {
                db.AddParameter("@UID", user);
                db.AddParameter("@RID", role);
                db.ExecuteNonQuery("INSERT INTO USERROLES(USERNAME,ROLENAME) VALUES(@UID,@RID)");
            }
        }
    }
 
    public override void RemoveUsersFromRoles(string[] usernames, string[] roleNames)
    {
        foreach (string user in usernames)
        {
            foreach (string role in roleNames)
            {
                db.AddParameter("@UID", user);
                db.AddParameter("@RID", role);
                db.ExecuteNonQuery("DELETE FROM USERROLES WHERE USERNAME=@UID AND ROLENAME=@RID");
            }
        }
    }
 
    public override string[] GetRolesForUser(string username)
    {
        db.AddParameter("@UID", username);
        int reccount = (int)db.ExecuteScalar("SELECT COUNT(*) FROM USERROLES WHERE USERNAME=@UID");
        string[] roles = new string[reccount];
 
        db.AddParameter("@UID", username);
        SqlDataReader reader = (SqlDataReader)db.ExecuteReader("SELECT ROLENAME FROM USERROLES WHERE USERNAME=@UID");
        int i = 0;
        while (reader.Read())
        {
            roles[i] = reader.GetString(0);
            i++;
        }
        reader.Close();
        return roles;
    }
 
    public override string[] GetUsersInRole(string roleName)
    {
        db.AddParameter("@RID", roleName);
        int reccount = (int)db.ExecuteScalar("SELECT COUNT(*) FROM USERROLES WHERE ROLENAME=@RID");
        string[] users = new string[reccount];
 
        db.AddParameter("@RID", roleName);
        SqlDataReader reader = (SqlDataReader)db.ExecuteReader("SELECT USERNAME FROM USERROLES WHERE ROLENAME=@RID");
        int i = 0;
        while (reader.Read())
        {
            users[i] = reader.GetString(0);
            i++;
        }
        reader.Close();
        return users;
 
    }
 
    public override bool IsUserInRole(string username, string roleName)
    {
        db.AddParameter("@UID", username);
        db.AddParameter("@RID", roleName);
        object obj = db.ExecuteScalar("SELECT ROLENAME FROM USERROLES WHERE USERNAME=@UID AND ROLENAME=@RID");
        if (obj != null)
        {
            return true;
        }
        else
        {
            return false;
        }
    }
 
 
测试自定义 Provider
    在你下载的页面里包含了四个 Web 窗体-- default.aspx Login.aspx RoleManager.aspx UserRoles.aspx 。前面两个用于测试成员关系的 Provider 模型,后面两个用户测试角色的 Provider 模型。
我们使用了 ASP.NET2.0 提供的 Membership Roles 的基本功能,这些类会使用我们自定义的 Provider 来完成相应的工作
 
总结
   在本文我们我们可以看到自定义 Membership Role 是多么的简单。你可以扩展该功能来适用你的应用程序,你还可以扩展诸如加密解密等功能
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值