MVC網(wǎng)站開(kāi)發(fā)之權(quán)限管理篇
一、前言
剛到公司沒(méi)多長(zhǎng)時(shí)間就開(kāi)始接觸MVC到現(xiàn)在不能說(shuō)懂了,只能說(shuō)到達(dá)會(huì)用這個(gè)層次吧,感覺(jué)MVC用來(lái)寫(xiě)Web還是很強(qiáng)大的,層次清晰。
今天我來(lái)寫(xiě)寫(xiě)關(guān)于權(quán)限管理這一塊,自我感覺(jué)網(wǎng)站的權(quán)限主要分為菜單權(quán)限和角色權(quán)限,首先說(shuō)角色權(quán)限,比較簡(jiǎn)單不同角色可以看到不同頁(yè)面這就是角色權(quán)限,菜單權(quán)限也可以說(shuō)是操作權(quán)限,就是具體到某一個(gè)按鈕,或某一個(gè)下拉框的查看權(quán)限或使用權(quán)限。
二、角色權(quán)限
1.用戶(hù)角色
首先來(lái)角色權(quán)限,每個(gè)用戶(hù)有著多樣不同的角色,一對(duì)多的關(guān)系。
2.菜單管理
在菜單管理中我們就可以這樣管理,某一菜單,那一角色可以看到就打上√這樣比較容易控制。
3.數(shù)據(jù)庫(kù)
再來(lái)看數(shù)據(jù)庫(kù)中,要有角色的表以及用戶(hù)與角色關(guān)系表。
再就是角色與菜單的關(guān)系表,其中PermissionIDs字段為操作權(quán)限以|隔開(kāi)。
4.用戶(hù)登錄
當(dāng)用戶(hù)登錄時(shí)我們就可以根據(jù)登陸人的ID取到他的所有角色存到Session中,并根據(jù)登錄人查出相應(yīng)的菜單。
//角色基本信息 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; } //權(quán)重 public int Weight { get; set; } }
前臺(tái)代碼:
<div data-options="region:'west',split:true" title="導(dǎo)航菜單" 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>沒(méi)有可用菜單</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; }
菜單類(lèi):
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()方法就是根據(jù)用戶(hù)名獲取菜單列表結(jié)構(gòu),我這里用戶(hù)名在數(shù)據(jù)庫(kù)中是唯一的,在這里注意一點(diǎn)比較麻煩的是根據(jù)類(lèi)可以看出菜單是有父菜單子菜單的所以方法中需要有兩個(gè)循環(huán)去添加。
三、菜單權(quán)限
也就是操作權(quán)限,比如某一按鈕的操作權(quán)限。首先我們把所有關(guān)于按鈕的操作權(quán)限存放到一個(gè)類(lèi)中,(有更好的方法請(qǐng)向我推薦謝謝)
public class Menus { public static int gongdan = 503000000;//任務(wù)工單 }
然后我們需要操作權(quán)限的按鈕所在的頁(yè)面的Controllers(加載頁(yè)面)中存到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); //上報(bào)施工計(jì)劃 return View(); }
/// <summary> /// 判斷某權(quán)限是否在獲取某角色權(quán)限的列表中 /// </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> /// 獲取某角色權(quán)限的列表 /// </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> /// 獲取某菜單某角色下具有的權(quán)限 /// </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; }
最后一個(gè)方法中運(yùn)用到了EF根據(jù)菜單以及角色獲取某菜單某角色下具有的權(quán)限
前臺(tái)就非常簡(jiǎn)單的:
@if (ViewBag.IsReportPlan == true) { @: <a href="#" class="easyui-linkbutton l-btn" iconcls="icon-add">按鈕</a> }
四、尾聲
總結(jié)一下,就是首先要有一個(gè)菜單管理的模塊,它不但可以管理菜單還可以管理菜單中的權(quán)限以及每個(gè)角色關(guān)于菜單的權(quán)限,然后就是后臺(tái)的控制,上面權(quán)限Model中存的權(quán)重,指的是每一角色都有權(quán)重,每一個(gè)用戶(hù)都有他的最大權(quán)重,根據(jù)這個(gè)權(quán)重我們就可以做很多條件的控制,簡(jiǎn)單的說(shuō)也是為了方便吧。
第一篇技術(shù)文檔,文筆還需要多鍛煉,以后會(huì)試著多寫(xiě)博文,不會(huì)寫(xiě)文檔的碼農(nóng)不是好程序員。
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- IIS7/IIS7.5/IIS8網(wǎng)站目錄執(zhí)行權(quán)限設(shè)置方法(與IIS6不同)
- Win2008 R2中IIS7.5配置完網(wǎng)站權(quán)限不足問(wèn)題的解決方法
- IIS PHP環(huán)境Temp文件夾的權(quán)限問(wèn)題引起的網(wǎng)站故障
- win2003 IIS虛擬主機(jī)網(wǎng)站防木馬、權(quán)限設(shè)置、安全配置整理
- Apache Wind2003 配置網(wǎng)站目錄權(quán)限小結(jié)
- ASP.NET MVC5網(wǎng)站開(kāi)發(fā)之登錄、驗(yàn)證和注銷(xiāo)管理員篇1(六)
- ASP.NET MVC5網(wǎng)站開(kāi)發(fā)之實(shí)現(xiàn)數(shù)據(jù)存儲(chǔ)層功能(三)
- vs2010制作簡(jiǎn)單的asp.net網(wǎng)站
- 如何對(duì)ASP.NET網(wǎng)站實(shí)現(xiàn)靜態(tài)化
- ASP.NET MVC5網(wǎng)站開(kāi)發(fā)管理列表、回復(fù)及刪除(十三)
相關(guān)文章
ASP.NET Core實(shí)現(xiàn)多文件上傳
這篇文章介紹了ASP.NET Core實(shí)現(xiàn)多文件上傳的方法,文中通過(guò)示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-01-01asp.net 數(shù)據(jù)綁定 使用eval 時(shí)候報(bào) 字符文本中的字符太多 問(wèn)題的解決方法
asp.net 數(shù)據(jù)綁定 使用eval 時(shí)候報(bào) 字符文本中的字符太多 問(wèn)題解決,需要的朋友可以參考下。2010-09-09asp.net checkbox 動(dòng)態(tài)綁定id GridView刪除提示
asp.net checkbox 動(dòng)態(tài)綁定id,需要的朋友可以參考下。雖然簡(jiǎn)單但不知道挺麻煩的。GridView刪除提示2009-10-10.net core版 文件上傳/ 支持批量上傳拖拽及預(yù)覽功能(bootstrap fileinput上傳文件)
本篇內(nèi)容主要解決.net core中文件上傳的問(wèn)題 開(kāi)發(fā)環(huán)境:ubuntu+vscode.本文給大家介紹的非常詳細(xì),感興趣的朋友一起看看吧2017-03-03Asp.net core利用IIS在windows上進(jìn)行托管步驟詳解
這篇文章主要給大家介紹了關(guān)于A(yíng)sp.net core利用IIS在windows上進(jìn)行托管步驟的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧。2018-03-03.NET下文本相似度算法余弦定理和SimHash淺析及應(yīng)用實(shí)例分析
這篇文章主要介紹了.NET下文本相似度算法余弦定理和SimHash淺析及應(yīng)用,實(shí)例形式詳細(xì)講述了相似度算法余弦定理和SimHash的原理與用法,需要的朋友可以參考下2015-01-01asp.net微信開(kāi)發(fā)(開(kāi)發(fā)者接入)
這篇文章主要介紹了asp.net微信開(kāi)發(fā)中有關(guān)開(kāi)發(fā)者接入的相關(guān)內(nèi)容,需要的朋友可以參考下2015-11-11