• 角色权限模块


    上下文:一般系统都会有不同的用户角色,比如系统管理员admin,超级用户manager,一般用户worker
    早先直接使用session保留一个值,如session["userType"].来判断用户的权限。
    特点:方便,但是毕竟不同角色,属性数量和类型是不相同的,比如一个中介管理系统中:
    admin:
    channelID;所属中介机构
    loginID;登陆id
    realName;真实姓名

    manager和worker
    channelID;所属中介机构
    loginID;登陆id
    realName;真实姓名
    groupID;所属团队
    level;级别(manager,work)
    level2;附加权限

    可能以后还会继续添加更多不同属性。
    潜在问题:会有空session引用问题。
    如果是admin登陆。admin是没有groupID变量的。但是程序中出现 session["groupID"]这个是错误的。
    即使session["groupid"]赋个空直,但会有很多潜在的bug。


    最先反应的解决方案
    不直接使用session而用3个类worker,manager,admin的属性来得到(session中保留一个对象,就是这3个类的实例)
    类根据session["userType"]来得到角色级别。
    如:if("1"==session["userType"]){worker me=new worker()}
    解决了不同角色用户自己的变量的问题。
    问题是原来可以直接通过 session["loginID"]来得到用户登陆id。现在直接用类不行了,要先得到不同类,再取直
    getinfo()
    {
    string loginid="";
    if("1"==session["userType"]){worker me=new worker();loginid=me.loginid;}
    else
    {....}
    }


    那么自然我们会想到定义基类和继承。

    解决方案之一
    当然是我们熟悉的类继承。大家都知道继承,但是用不用是另外一回事。
    父类:baseuser
    子类:worker,admin,manager


    public class baseUser
        {
            public readonly int channelID;
            public readonly string loginID;
            public readonly string realName;
            public readonly webenum.userType level;

            public baseUser(int channelid, string loginid, string realname, webenum.userType levela)
            {
                channelID = channelid;
                loginID = loginid;
                realName = realname;
                level = levela;
            }
        }

        public class worker:baseUser
        {
            public readonly string level2;
            public readonly int groupID;

            public worker(int channelid, string loginid, string realname, string level2a, int groupid):base(channelid,loginid,realname,webenum.userType.worker)
            {
                level2 = level2a;
                groupID = groupid;
            }
        }

        public class manager : baseUser
        {
            public readonly string level2;
            public readonly int groupID;

            public manager(int channelid, string loginid, string realname,string level2a, int groupid)
                : base(channelid, loginid, realname, webenum.userType.groupmanage)
            {
                level2 = level2a;
                groupID = groupid;
            }
        }

        public class admin : baseUser
        {
            public admin(int channelid, string loginid, string realname)
                : base(channelid, loginid, realname, webenum.userType.admin)
            { }
        }


    看下我们怎么初始化
    if ("0" == type)
                {
                    zjpx.BLL.zj_worker bllworker = new zjpx.BLL.zj_worker();
                    zjpx.Model.zj_worker me= bllworker.loginCheck(loginname, psw);
                    if (me!=null)
                    {
                        if (me.w_level == (int)WebUtility.webenum.userType.groupmanage)
                        {
                            WebUtility.baseUser userInfo = new channelpx.WebUtility.manager(me.w_zj, me.w_name, me.w_rname,me.w_level2, me.w_tuandui);
                            Session["userinfo"] = userInfo;
                        }
                        else if(me.w_level==(int)WebUtility.webenum.userType.worker)
                        {
                            WebUtility.baseUser userInfo = new channelpx.WebUtility.worker(me.w_zj, me.w_name, me.w_rname, me.w_level2, me.w_tuandui);
                            Session["userinfo"] = userInfo;
                        }
                    }
                }
                //管理员
                else
                {
                    //zjpx.Model.zj_worker me = bllworker.loginCheck(loginname, psw);
                    if (true)
                    {
                        WebUtility.baseUser userInfo = new channelpx.WebUtility.admin(6, loginname,"");
                        Session["userinfo"] = userInfo;
                    }
                }

    第一个问题:不直接使用session,不会有空引用session的问题,或错误session问题。
    第二个问题:使用了基类,可以直接使用共有属性。

    Model.zj_worker me= bllworker.loginCheck(loginname, psw);
    baseUser userInfo = new worker(me.w_zj, me.w_name, me.w_rname,me.w_level, me.w_level2, me.w_tuandui,WebUtility.webenum.userType.groupmanage);
    Session["userinfo"] = userInfo;

    直接使用session["userinfo"]。
    要知道它是哪个子类。
    可以
    public static bool isgroupmanage()
            {
                if (HttpContext.Current.Session["userinfo"] != null && typeof(manager) == HttpContext.Current.Session["userinfo"].GetType())
                {
                    return true;
                }
                else
                {
                    return false;
                }
            }

    之后可以转为子类
    admin myadmin=(admin)me;


    ps:

    1.可以写一个自定义继承于page的类,比如 adminpage:page
    public class adminpage:basepage
        {
            public new WebUtility.admin me;
            protected override void OnPreInit(EventArgs e)
            {
                base.OnPreInit(e);
                if (!WebUtility.userHelper.isadmin())
                {
                    HttpContext.Current.Response.Redirect("/nolevel.aspx");
                }
                else
                {
                    me = (WebUtility.admin)base.me;
                }
            }
        }

    里面定义一个属性public new WebUtility.admin me;(隐藏基类的me)
    再让管理员管理的页面继承于adminpage这个类。那么我们就可以直接使用me这个类了。还可以在adminpage里面做很多基础操作。

    管理员和普通登陆用户的通用页面可以定义属性 baseuser(基类)

    public class basepage:Page
        {
            public WebUtility.baseUser me;
            protected override void OnPreInit(EventArgs e)
            {
                if (!WebUtility.userHelper.checkLogin())
                {
                    Response.Redirect("/login.aspx", true);
                }
                else
                {
                    me = (WebUtility.baseUser)Session["userinfo"];
                }
                base.OnPreInit(e);
            }
        }

    继承不同的类。我们得到的me是不同类的实例。


    2.
    既然提供了枚举,还是用枚举来替换简单的int 的1,2,3来表示用户级别。

  • 相关阅读:
    经典面试题目C语言
    论C语言中二级指针和二维数组之间的区别
    判断单链表中是否有环找到环的入口节点
    论decltype和auto的区别
    在ubuntu下安装opencv
    C中有关引用和指针的异同
    (四)关于读文件的结束的判别方法(EOF和feof)以及区别
    (三)论sizeof与strlen之间的区别
    (二)C语言文本流和二进制流的区别
    (一)C的编译,printf,规范化
  • 原文地址:https://www.cnblogs.com/lsfv/p/1563746.html
Copyright © 2020-2023  润新知