本博客文章为转载,请勿用于商业目的!
本博客文章为转载,请勿用于商业目的!
前言

  最近在学习ASP.NET,发现了几个有趣的类,比如自定义用户配置提供程序ProfileProvider,成员提供程序MembershipProvider,角色管理RoleProvider,会话状态SessionStateStoreProvider,这几个类经常作为权限相关设置,但是默认这几个类都必须使用定制的数据库,因此造成诸多限制

  但如果重写这些类,然后配合.NET原有的API来使用,这样一来用着方便,二来由于提供程序是自定义的,能够满足自己的要求

  于是小弟我试着重写这些类,分享自己的一些心得体会,希望各位前辈能够多多指教啦

  实现自定义用户配置提供程序ProfileProvider

  一。说明

  在ASP.NET中,可以在web.config文件设置用户个性配置,然后在代码中这么写

    using System.Web.Profile;

    protected void Page_Load(object sender, EventArgs e)
    {

        Profile.A = 123;
        Profile.B = "wahahaha";

    }

  这样看似确实很方便,但是缺点就是如果要使用这个用户个性配置,默认是使用SqlProfileProvider,连数据库相关的表都被定死了

  唯一的办法就是重写此类,然后让其支持自定义数据库,甚至是支持XML,TXT或者能够想到的任何可以存储信息的媒介

  在重写之前,首先要了解该类的一些需要重写的方法和属性

  属性

  string ApplicationName{get,set} 返回和设置应用程序名

  string Name{get} 返回提供程序的名称

  string Description{get} 返回一些描述

  方法

  void Initialize(string name, System.Collections.Specialized.NameValueCollection config) 初始化用的

int DeleteProfiles(string[] usernames) 根据用户名集合来删除用户的个性信息,并返回影响行数

  int DeleteProfiles(ProfileInfoCollection profiles) 根据用户信息来删除用户的个性信息,并返回影响行数

  ProfileInfoCollection GetAllProfiles(ProfileAuthenticationOption authenticationOption, int pageIndex, int pageSize, out int totalRecords) 获取所有的个性信息,ProfileAuthenticationOption 枚举用于定义是返回匿名用户的还是登陆用户的还是全部的,两个INT型参数用于分页,最后的那个INT参数用于获取返回的行的总数

  int DeleteInactiveProfiles(ProfileAuthenticationOption authenticationOption, DateTime userInactiveSinceDate) 删除超时用户的信息

  SettingsPropertyValueCollection GetPropertyValues(SettingsContext context, SettingsPropertyCollection collection) 返回当前用户的个性信息

  void SetPropertyValues(SettingsContext context, SettingsPropertyValueCollection collection) 设置当前用户的个性信息

  还有4个方法,比如

  GetNumberOfInactiveProfiles(),FindInactiveProfilesByUserName(),FindProfilesByUserName(),GetAllInactiveProfiles()都是根据条件检索个性信息用的,实现相对简单

  二。实现

  1.新建立一个项目,然后在App_Data中,添加一个SQL数据库,建立一个表,命名为test1,在表中建立以下字段

  UserName  varchar 主键

  A int (本次实验中自定义的一个字段)

  B varchar (本次实验中自定义的一个字段)

  IsAnonymous bit 是否为匿名用户

  LastActivityDate datetime 最后访问时间

LastUpdateDate datetime 最后更新时间

  2.导入sqlCtrl类(此类专门用于操作数据库,源码中有)

  3.接下来是关键示例代码

using System.Web.Profile;
    public class DefinePro : ProfileProvider
    {
        public DefinePro()
        {
            //
            //TODO: 在此处添加构造函数逻辑
            //
        }

        private string applicationName;

        public override string ApplicationName
        {
            get
            {
                return applicationName;
            }
            set
            {
                applicationName = value;
            }
        }

        public override string Name
        {
            get
            {
                return "DefinePro";
            }
        }

        public override string Description
        {
            get
            {

                return "其实没啥好说得";
            }
        }

        public override void Initialize(string name, System.Collections.Specialized.NameValueCollection config)
        {
            name = "DefinePro";
            base.Initialize(name, config);//调用基类的初始化函数
            ApplicationName = System.Web.Hosting.HostingEnvironment.ApplicationVirtualPath;//获得当前应用程序名称
        }

        public override int DeleteProfiles(string[] usernames)
        {
            string a = string.Empty;
            foreach (string b in usernames)
            {
                a += "'" + b + "',";
            }
            a.TrimEnd(',');
            try
            {
                new SqlCtrl().RunCmd("Delete test1 where UserName in(" + a + ")");//从刚才建立得那个数据库中删行
                return 1;
            }
            catch
            {
                return 0;
            }
        }

        public override int DeleteProfiles(ProfileInfoCollection profiles)
        {
            try
            {
                new SqlCtrl().RunCmd("Delete test1 where UserName ='" + profiles["UserName"].ToString() + "'");
                return 1;
            }
            catch
            {
                return 0;
            }
        }

public override ProfileInfoCollection GetAllProfiles(ProfileAuthenticationOption authenticationOption, int pageIndex, int pageSize, out int totalRecords)
        {
            totalRecords = 0;//这里设置为0是因为偷懒..原本是需要返回查询的行的总数行的总数
            ProfileInfoCollection pc = new ProfileInfoCollection();
            switch (authenticationOption)
            {
                case ProfileAuthenticationOption.All:
                    {

                        SqlDataReader rd = new SqlCtrl().GetDataReader("Select * from test1 limit " + pageIndex + "," + pageSize);
                        while (rd.Read())
                        {
                         pc.Add(new ProfileInfo(rd[0].ToString(), rd.GetBoolean(3), rd.GetDateTime(4), rd.GetDateTime(5), 0));
                        }
                        return pc;
                    };
                    break;
                case ProfileAuthenticationOption.Anonymous:
                    {
                              SqlDataReader rd = new SqlCtrl().GetDataReader("Select * from test1 where IsAnonymous=false limit " + pageIndex + "," + pageSize);
                        while (rd.Read())
                        {
                         pc.Add(new ProfileInfo(rd[0].ToString(), rd.GetBoolean(3), rd.GetDateTime(4), rd.GetDateTime(5), 0));
                        }
                        return pc;
                    };
                    break;
                case ProfileAuthenticationOption.Authenticated:
                    {
                        SqlDataReader rd = new SqlCtrl().GetDataReader("Select * from test1 where IsAnonymous=true limit " + pageIndex + "," + pageSize);
                        while (rd.Read())
                        {
                         pc.Add(new ProfileInfo(rd[0].ToString(), rd.GetBoolean(3), rd.GetDateTime(4), rd.GetDateTime(5), 0));
                        }
                        return pc;
                    };
                    break;
                default: return pc; break;
            }
        }

 public override int DeleteInactiveProfiles(ProfileAuthenticationOption authenticationOption, DateTime userInactiveSinceDate)
        {
            try
            {

                switch (authenticationOption)
                {
                    case ProfileAuthenticationOption.All: new SqlCtrl().RunCmd("Delete test1 where LastActivityDate <" + userInactiveSinceDate.ToString()); break;
                    case ProfileAuthenticationOption.Anonymous: new SqlCtrl().RunCmd("Delete test1 where IsAnonymous=false and LastActivityDate <" + userInactiveSinceDate.ToString()); break;
                    case ProfileAuthenticationOption.Authenticated: new SqlCtrl().RunCmd("Delete test1 where IsAnonymous=true and LastActivityDate <" + userInactiveSinceDate.ToString()); break;
                }
                return 1;//这里返回1表示操作成功
            }
            catch
            {
                return 0;//表示操作失败
            }
        }

        public override SettingsPropertyValueCollection GetPropertyValues(SettingsContext context, SettingsPropertyCollection collection)
        {

            SettingsPropertyValueCollection spvc = new SettingsPropertyValueCollection();
            SqlCtrl sc = new SqlCtrl();

            SqlDataReader sr = sc.GetDataReader("Select * from test1 where UserName='" + context["UserName"].ToString() + "'");
            int a = 0;
            string b = string.Empty;

            if (sr.Read())
            {
                a = sr.GetInt32(1);
                b = sr.GetString(2);
            }

                foreach (SettingsProperty prop in collection)
                {
                    SettingsPropertyValue pv = new SettingsPropertyValue(prop);
                    switch (prop.Name)
                    {
                        case "A": pv.PropertyValue = a; break;
                        case "B": pv.PropertyValue = b; break;
                    }
                    spvc.Add(pv);

                }
                //在retrun之前,这里明显还要设置一下更新激活时间语句,但时间关系所以省略了。。
                return spvc;
           
            


        }

        public override void SetPropertyValues(SettingsContext context, SettingsPropertyValueCollection collection)
        {
            SqlCtrl sc = new SqlCtrl();
            SqlDataReader a = sc.GetDataReader("Select * from test1 where UserName='" + context["UserName"].ToString() + "'");
            //如果有行就更新,没行就新建
            if (a.Read())
            {
                a.Dispose();
                sc.RunCmd("update test1 set A=" + Convert.ToInt32(collection["A"].PropertyValue) + ",B='" + collection["B"].PropertyValue.ToString() + "',LastActivityDate='" + DateTime.Now.ToString() + "',LastUpdatedDate='" + DateTime.Now.ToString() + "' where UserName='" + context["UserName"].ToString() + "'");

            }
            else
            {
                string cc = "insert into test1 (UserName,A,B,IsAnonymous,LastActivityDate,LastUpdatedDate) values ('" + context["UserName"].ToString() + "'," + collection["A"].PropertyValue.ToString() + ",'" + collection["B"].PropertyValue.ToString() + "wc" + "','" + !((bool)(context["IsAuthenticated"])) + "','" + DateTime.Now.ToString() + "','" + DateTime.Now.ToString() + "')";
                a.Dispose();
                sc.RunCmd(cc);
            }
        }
    }
 4.修改Web.config文件

<configuration>
    <appSettings/>
    <connectionStrings>
        <add name="ConnectionString1" connectionString="Data Source=.SQLEXPRESS;AttachDbFilename=|DataDirectory|Database.mdf;Integrated Security=True;User Instance=True" providerName="System.Data.SqlClient"/>
    </connectionStrings>
    <system.web>
        <compilation debug="true">
        </compilation>
        <authentication mode="Windows"/>
        <anonymousIdentification enabled="true"/>
        <profile defaultProvider="DefinePro">
            <providers>
                                <clear/>
                <add name="DefinePro" type="DefinePro" connectionStringName="ConnectionString1"   />
                                <!--关键就是这里的type="DefinePro" 就可以使用了 -->
            </providers>
            <properties>
                <add name="A" allowAnonymous="true" type="System.Int32"/>
                <add name="B" allowAnonymous="true"/>
            </properties>
        </profile>
    </system.web>
</configuration>

 

  5.接下来就可以直接使用了

    using System.Web.Profile;

    protected void Page_Load(object sender, EventArgs e)
    {

        Profile.A = 123;
        Profile.B = "wahahaha";

    }

 

posted on 2010-03-30 23:43  刘季  阅读(208)  评论(0编辑  收藏  举报