视频1 视频21 视频41 视频61 视频文章1 视频文章21 视频文章41 视频文章61 推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37 推荐39 推荐41 推荐43 推荐45 推荐47 推荐49 关键词1 关键词101 关键词201 关键词301 关键词401 关键词501 关键词601 关键词701 关键词801 关键词901 关键词1001 关键词1101 关键词1201 关键词1301 关键词1401 关键词1501 关键词1601 关键词1701 关键词1801 关键词1901 视频扩展1 视频扩展6 视频扩展11 视频扩展16 文章1 文章201 文章401 文章601 文章801 文章1001 资讯1 资讯501 资讯1001 资讯1501 标签1 标签501 标签1001 关键词1 关键词501 关键词1001 关键词1501 专题2001
MVC网站开发之权限管理篇
2020-11-27 22:36:35 责编:小采
文档

一、前言

刚到公司没多长时间就开始接触MVC到现在不能说懂了,只能说到达会用这个层次吧,感觉MVC用来写Web还是很强大的,层次清晰。

今天我来写写关于权限管理这一块,自我感觉网站的权限主要分为菜单权限和角色权限,首先说角色权限,比较简单不同角色可以看到不同页面这就是角色权限,菜单权限也可以说是操作权限,就是具体到某一个按钮,或某一个下拉框的查看权限或使用权限。

二、角色权限

1.用户角色

首先来角色权限,每个用户有着多样不同的角色,一对多的关系。

2.菜单管理

在菜单管理中我们就可以这样管理,某一菜单,那一角色可以看到就打上√这样比较容易控制。

3.数据库

再来看数据库中,要有角色的表以及用户与角色关系表。

再就是角色与菜单的关系表,其中PermissionIDs字段为操作权限以|隔开。

4.用户登录

当用户登录时我们就可以根据登陆人的ID取到他的所有角色存到Session中,并根据登录人查出相应的菜单。 

//角色基本信息
 SqlHelperParameter sqlHelperParameterRole = new SqlHelperParameter();
 sqlHelperParameterRole.Add("UserId", dtUserRow["UserId"].ToString());
 DataTable dtRole = SqlHelper.ExecuteDataTable(@"
 select 
 Sys_Roles.RoleId,
 Sys_Roles.RoleName,
 Sys_Roles.Weight 
 from (
 select UserId,RoleId from Sys_UsersInRoles 
 where UserId =@UserId
 ) as a left join Sys_Roles on a.RoleId = Sys_Roles.RoleId", sqlHelperParameterRole);
 int dtRoleCount = dtRole.Rows.Count;
 RoleWeightMax = int.MaxValue;
 for (int i = 0; i < dtRoleCount; i++)
 {
 RolesSession rs = new RolesSession();
 rs.RoleID = Guid.Parse(dtRole.Rows[i]["RoleId"].ToString());
 rs.RoleName = dtRole.Rows[i]["RoleName"].ToString();
 rs.Weight = Convert.ToInt32(dtRole.Rows[i]["Weight"]);
 if (RoleWeightMax > rs.Weight)
 {
 RoleWeightMax = rs.Weight;
 }
 RoleList.Add(rs);
 }
public class RolesSession
 {
 public Guid RoleID { get; set; }
 public string RoleName { get; set; }
 //权重
 public int Weight { get; set; }
 }

前台代码:

 <div data-options="region:'west',split:true" title="导航菜单" style="width: 200px; padding1: 1px;
 overflow: hidden;" id="left_nav">
 <div class="easyui-accordion" data-options="fit:true,border:false">
 @H9C.PMS.BLL.LogOn.MenuList.GetMenu(ViewBag.UserName)
 </div>
</div>

控制器: 

public static MvcHtmlString GetMenu(string userName)
 {
 Menu menu = new Menu();
 MenuStructure ms = menu.GetMenuListStructure(userName);
 if (ms != null)
 {
 ms.Children.Remove(ms.Children.FirstOrDefault(o => o.ModelCode == "0" && o.ParentID == "0"));
 }
 return new MvcHtmlString(MenuNav("0", ms));
 }

 private static string MenuNav(string menuCode, MenuStructure menuStruc)
 {
 if (menuStruc == null)
 {
 return "<div>没有可用菜单</div>";
 }
 List<MenuStructure> list = menuStruc.Children.Where(m => m.ParentID == menuCode).ToList();
 StringBuilder sbMenu = new StringBuilder();

 foreach (var item in list)
 {
 if (item.ParentID == "0")
 {
 sbMenu.Append("<div title=\"" + item.Title + "\" style=\"overflow: auto;\">");
 sbMenu.Append("<ul id=\"menu" + item.ParentID + "\" class=\"easyui-tree\" animate=\"true\" dnd=\"true\">");
 sbMenu.Append("<li>");

 }
 else
 {
 sbMenu.Append("<ul id=\"menu" + item.ParentID + "\" class=\"easyui-tree\" animate=\"true\" dnd=\"true\">");
 if (item.Children.Count == 0)
 {
 sbMenu.Append("<li>");
 }
 else
 {
 sbMenu.Append("<li state=\"closed\">");
 }
 }

 sbMenu.Append("<span>");

 if (item.Url == "/")
 {
 sbMenu.Append("<a class=\"e-submenu\" href=\"javascript:void(0);\" title=\"" + item.Title + "\" >");
 }
 else
 {
 string tabsIcon = "14";
 if (!string.IsNullOrWhiteSpace(item.Icon))
 {
 tabsIcon = item.Icon.Replace("/Content/images/", "").Replace(".png", "");
 }
 sbMenu.Append("<a class=\"e-submenu\" href=\"#\" onclick=\"addTab('" + item.Url + "','" + item.Title + "')\" >");
 sbMenu.Append("<img src=\"" + item.Icon + "\" >");
 }

 sbMenu.Append("" + item.Title + "");
 sbMenu.Append("</a></span>");
 if (IsExistParent(item.ModelCode, item))
 {
 sbMenu.Append(MenuNav(item.ModelCode, item));
 }
 sbMenu.Append("</li>");
 sbMenu.Append("</ul>");


 if (item.ParentID == "0")
 {
 sbMenu.Append("</div>");
 }

 }
 return sbMenu.ToString();
 }

 private static bool IsExistParent(string modelCode, MenuStructure menuModels)
 {
 var query = menuModels.Children.FirstOrDefault(m => m.ParentID == modelCode);
 if (query == null)
 {
 return false;
 }
 return true;
 }

菜单类: 

public class MenuStructure
 {
 public string ModelCode;
 public string Title;
 public string Icon;
 public string Url;
 public string ParentID;
 public List<MenuStructure> Children = new List<MenuStructure>();
 }

其中GetMenuListStructure()方法就是根据用户名获取菜单列表结构,我这里用户名在数据库中是唯一的,在这里注意一点比较麻烦的是根据类可以看出菜单是有父菜单子菜单的所以方法中需要有两个循环去添加。 

三、菜单权限
也就是操作权限,比如某一按钮的操作权限。首先我们把所有关于按钮的操作权限存放到一个类中,(有更好的方法请向我推荐谢谢)

public class Menus
 {
 public static int gongdan = 503000000;//任务工单
 } 

然后我们需要操作权限的按钮所在的页面的Controllers(加载页面)中存到ViewBag里,如下: 

public ActionResult Index()
 {H9C.PMS.BLL.RBAC.Permission pm = new BLL.RBAC.Permission();
ViewBag.IsReportPlan = pm.IsRoleHavePermissions(Roles.Shigongduizhang, Menus.gongdan, base.UserSessionModel, Menus.GongdanReportPlanByShiGongTeamer); //上报施工计划


 return View();
 }

/// <summary>
 /// 判断某权限是否在获取某角色权限的列表中
 /// </summary>
 /// <param name="roleId"></param>
 /// <param name="modelCode"></param>
 /// <param name="userSessionModel"></param>
 /// <param name="permissionCode"></param>
 /// <returns></returns>
 public bool IsRoleHavePermissions(Guid roleId, int modelCode, UserSessionModel userSessionModel, int permissionCode)
 {
 List<PermissionModel> permissionModelList = this.GetRolePermissionList(roleId, modelCode, userSessionModel);
 if (permissionModelList == null)
 {
 return false;
 }
 foreach (var o in permissionModelList)
 {
 if (o.PCode == permissionCode)
 {
 return true;
 }
 }
 return false;
 }

/// <summary>
 /// 获取某角色权限的列表
 /// </summary>
 /// <param name="roleId"></param>
 /// <param name="modelCode"></param>
 /// <param name="userSessionModel"></param>
 /// <returns></returns>
 public List<PermissionModel> GetRolePermissionList(Guid roleId, int modelCode, UserSessionModel userSessionModel)
 {
 foreach (var o in userSessionModel.RoleList)
 {
 if (o.RoleID == roleId)
 {
 List<Model.RBAC.PermissionModel> permissionList = this.PermissionList(roleId, modelCode);
 return permissionList;
 }
 }
 return null;
 }

/// <summary>
 /// 获取某菜单某角色下具有的权限
 /// </summary>
 /// <param name="modelId"></param>
 /// <param name="menuId"></param>
 /// <returns></returns>
 public List<PermissionModel> PermissionList(Guid roleId, int menuId)
 {
 List<PermissionModel> pmList = new List<PermissionModel>();
 using (RBACContext connEF = new RBACContext())
 {
 Sys_Role_Model_Permissions srmp = connEF.Sys_Role_Model_Permissions.FirstOrDefault(o => o.ModelID == menuId && o.RoleId == roleId);
 if (srmp != null)
 {
 string permissions = srmp.PermissionIDs;
 if (!string.IsNullOrWhiteSpace(permissions))
 {
 string[] pids = permissions.Split(new char[] { '|' });
 for (int i = 0; i < pids.Length; i++)
 {
 if (!string.IsNullOrWhiteSpace(pids[i]))
 {
 pmList.Add(new PermissionModel() {
 ModelCode = menuId,
 PCode = Convert.ToInt32(pids[i]),
 PName =""
 });
 }
 }
 }
 }
 }
 return pmList;
 }

最后一个方法中运用到了EF根据菜单以及角色获取某菜单某角色下具有的权限
前台就非常简单的: 

@if (ViewBag.IsReportPlan == true)
 {
 @:  
 <a href="#" class="easyui-linkbutton l-btn"
 iconcls="icon-add">按钮</a> 
 } 

四、尾声 

总结一下,就是首先要有一个菜单管理的模块,它不但可以管理菜单还可以管理菜单中的权限以及每个角色关于菜单的权限,然后就是后台的控制,上面权限Model中存的权重,指的是每一角色都有权重,每一个用户都有他的最大权重,根据这个权重我们就可以做很多条件的控制,简单的说也是为了方便吧。
第一篇技术文档,文笔还需要多锻炼,以后会试着多写博文,不会写文档的码农不是好程序员。

下载本文
显示全文
专题