1. 程式人生 > >【無私分享:從入門到精通ASP.NET MVC】從0開始,一起搭框架、做專案(8) 許可權管理,自定義許可權,擴充套件許可權

【無私分享:從入門到精通ASP.NET MVC】從0開始,一起搭框架、做專案(8) 許可權管理,自定義許可權,擴充套件許可權

索引

簡述

今天我們來做許可權的管理,這篇比較多 希望新手朋友慢慢消化

專案準備

我們用的工具是:VS 2013 + SqlServer 2012 + IIS7.5

希望大家對ASP.NET MVC有一個初步的理解,理論性的東西我們不做過多解釋,有些地方不理解也沒關係,會用就行了,用的多了,用的久了,自然就理解了。

專案開始

一、新建許可權控制器 繼承 基礎控制器

1、我們在Areas/SysManage/Controllers 下新建一個控制器 叫PermissionController

 1 using System;
 2 using System.Collections.Generic;
3 using System.Linq; 4 using System.Web; 5 using System.Web.Mvc; 6 7 namespace WebPage.Areas.SysManage.Controllers 8 { 9 public class PermissionController : Controller 10 { 11 // GET: SysManage/Permission 12 public ActionResult Index() 13 { 14 return
View(); 15 } 16 } 17 }

2、我們讓PermissionController 繼承基礎控制器 BaseController 這裡需要新增引用 using WebPage.Controllers

3、我們新增需要的介面宣告,這裡需要新增引用 using Service.IService

 1  public class PermissionController : BaseController
 2     {
 3         #region 宣告容器
 4         /// <summary>
5 /// 系統管理 6 /// </summary> 7 ISystemManage SystemManage { get; set; } 8 /// <summary> 9 /// 許可權管理 10 /// </summary> 11 IPermissionManage PermissionManage { get; set; } 12 /// <summary> 13 /// 模組管理 14 /// </summary> 15 IModuleManage ModuleManage { get; set; } 16 #endregion 17 18 public ActionResult Index() 19 { 20 return View(); 21 } 22 }

4、千萬不要忘記  我們新增xml的注入配置 (Config/Controllers.xml)

配置注入:

完整程式碼:

 1 <?xml version="1.0" encoding="utf-8" ?>
 2 <objects xmlns="http://www.springframework.net">
 3   <description>Spring注入控制器,容器指向Service層封裝的介面</description>
 4   <!--系統管理 Begin-->
 5   <!--主頁控制器-->
 6   <object type="WebPage.Areas.SysManage.Controllers.HomeController,WebPage" singleton="false">
 7     <property name="ModuleManage" ref="Service.Module"/>
 8   </object>
 9   <!--登入控制器-->
10   <object type="WebPage.Areas.SysManage.Controllers.AccountController,WebPage" singleton="false">
11     <property name="UserManage" ref="Service.User"/>
12   </object>
13   <!--模組管理-->
14   <object type="WebPage.Areas.SysManage.Controllers.ModuleController,WebPage" singleton="false">
15     <property name="ModuleManage" ref="Service.Module"/>
16     <property name="PermissionManage" ref="Service.Permission"/>
17     <property name="SystemManage" ref="Service.System"/>
18   </object>
19   <!--許可權管理-->
20   <object type="WebPage.Areas.SysManage.Controllers.PermissionController,WebPage" singleton="false">
21     <property name="ModuleManage" ref="Service.Module"/>
22     <property name="SystemManage" ref="Service.System"/>
23     <property name="PermissionManage" ref="Service.Permission"/>
24   </object>
25   <!--系統管理 end-->
26 </objects>
View Code

 OK,這樣 控制器和容器宣告 我們就完成了~

二、新增側欄選擇

我們把許可權管理的頁面 分左右兩欄 左欄是所有的模組  右欄是許可權

效果是這樣的:

1、我們新建一個Home檢視頁 這個檢視頁的作用就是 左右分欄 並新增許可權驗證

 

2、我們轉到檢視頁 新增樣式和佈局  這裡前端各人有個人的寫法 我就不詳細介紹了

我們先來做左欄 載入系統模組,我們新增一個下拉選單,讓使用者選擇操作的系統

1 <select id="sel-system" >
2 <option value="選擇系統"></option>
3 </select>

這裡的下拉選項,我們是應該輸出到頁面上的,所以 我們在 檢視Home 下面獲取這個系統集合

 1         /// <summary>
 2         /// 許可權管理 預設頁面
 3         /// </summary>
 4         /// <returns></returns>
 5         [UserAuthorizeAttribute(ModuleAlias = "Permission", OperaAction = "View")]
 6         public ActionResult Home()
 7         {
 8             try
 9             {
10                 //獲取使用者可操作的系統列表
11                 ViewData["Systemlist"] = this.SystemManage.LoadSystemInfo(CurrentUser.System_Id);
12             }
13             catch(Exception e)
14             {
15                 WriteLog(Common.Enums.enumOperator.Select, "對模組許可權按鈕的管理載入導航頁:", e);
16             }
17 
18             return View();
19         }

我們修改一下select 的 option 通過接收 後臺的ViewData["Systemlist"] 輸出 下拉選項

1   <select id="sel-system">
2   @{
3       foreach (var item in ViewData["Systemlist"] as dynamic)
4       {
5         <option value="@item.ID">@item.NAME</option>
6        }
7     }
8   </select>

然後就是樹形選單了,以前用的是jquery.ztree.core-3.5  今天換一換  用 jstree,我們看一下jstree json的格式

1 $('#using_json_2').jstree({ 'core' : {
2     'data' : [
3        { "id" : "ajson1", "parent" : "#", "text" : "Simple root node" },
4        { "id" : "ajson2", "parent" : "#", "text" : "Root node 2" },
5        { "id" : "ajson3", "parent" : "ajson2", "text" : "Child 1" },
6        { "id" : "ajson4", "parent" : "ajson2", "text" : "Child 2" },
7     ]
8 } });

當然,這是預設關閉的 展開呢 就是在屬性里加上"state": { "opened": true },我要關閉的,我就不加這個了,那麼按照這個格式,我們寫一個方法,返回我們模組的json資料

這個方法 我們起名叫做 GetTree

 1         /// <summary>
 2         /// 獲取模組樹形選單
 3         /// </summary>
 4         public ActionResult GetTree()
 5         {
 6             var json = new JsonHelper() { Msg = "Success", Status = "y" };
 7 
 8             //獲取系統ID
 9             var sysId = Request.Form["sysId"];
10 
11             //判斷系統ID是否傳入
12             if (string.IsNullOrEmpty(sysId))
13             {
14                 json.Status = "n";
15                 json.Msg = "獲取模組失敗!";
16                 return Json(json);
17             }          
18             try
19             {
20                 //獲取系統下的模組列表 按照 SHOWORDER欄位 升序排列
21                 var query = this.ModuleManage.LoadAll(p =>  p.FK_BELONGSYSTEM == sysId).OrderBy(p => p.SHOWORDER).ToList();
22 
23                 //這裡就是按照jsTree的格式 輸出一下 模組資訊
24                 var result = query.Select(m => new
25                 {
26                     id = m.ID,
27                     parent = m.PARENTID>0?m.PARENTID.ToString():"#",
28                     text = m.NAME,                    
29                     icon = m.LEVELS == 0 ? "fa fa-circle text-danger" : "fa fa-circle text-navy"
30                 }).ToList();
31 
32                 json.Data = result;
33             }
34             catch (Exception e)
35             {
36                 json.Status = "n";
37                 json.Msg = "伺服器忙,請稍後再試!";
38                 WriteLog(Common.Enums.enumOperator.Select, "許可權管理,獲取模組樹:", e);
39             }
40             return Json(json);
41         }

再回到我們Home檢視頁,用jstree呢 首先我們要引入它的css

然後引入它的js

我們在頁面中新建一個DIV 來存放這個樹形選單

寫個簡潔的ajax獲取資料 並且填充給上面那個DIV

$.post("/permission/gettree", { sysId: $("#sel-system").val() }, function (res) {
                if (res.Status == "y") {
                    $("#ModuleTree").jstree({
                        "core": { "multiple": false, "data": res.Data }
                    }).on("changed.jstree", function (e, data) {
                        alert(data.instance.get_node(data.selected).text);
                    });
                }
                else {
                    dig.error(res.Msg);
                }
            });

因為我們這個是要選擇系統 然後列出系統下的樹形選單的,所以我們把這個ajax方法 寫到一個function方法裡

 1  function ShowMoudle()
 2         {
 3             $("#ModuleTree").data('jstree', false).empty();
 4             $.post("/permission/gettree", { sysId: $("#sel-system").val() }, function (res) {
 5                 if (res.Status == "y") {
 6                     $("#ModuleTree").jstree({
 7                         "core": { "multiple": false, "data": res.Data }
 8                     }).on("changed.jstree", function (e, data) {
 9                         alert(data.instance.get_node(data.selected).text);
10                     });
11                 }
12                 else {
13                     dig.error(res.Msg);
14                 }
15             });
16         }

頁面開啟和系統下拉選單select 更改的時候 載入這個選單,下面是完整的

OK,是不是出來了

那接下來,我們要點選模組之後 操作模組的許可權,我們列出了樹形選單,上面做了一個方法就是 選中 選單的時候 彈出 選單的text

我們要做的是,點選選單的是後展示這個模組的許可權,所以,我們先新建一個許可權列表頁 

三、許可權管理

1、我們用Index這個檢視 來展示模組列表頁,我們給Index 新增許可權驗證 也是 檢視

1         /// <summary>
2         /// 許可權管理 許可權列表
3         /// </summary>
4         /// <returns></returns>
5         [UserAuthorizeAttribute(ModuleAlias = "Permission", OperaAction = "View")]
6         public ActionResult Index()
7         {
8             return View();
9         }

2、好的習慣,try  catch

 1      /// <summary>
 2         /// 許可權管理 許可權列表
 3         /// </summary>
 4         /// <returns></returns>
 5         [UserAuthorizeAttribute(ModuleAlias = "Permission", OperaAction = "View")]
 6         public ActionResult Index()
 7         {
 8             try
 9             {
10                 return View();
11             }
12             catch (Exception e)
13             {
14                 WriteLog(Common.Enums.enumOperator.Select, "對模組許可權按鈕的管理載入主頁:", e);
15                 throw e.InnerException;
16             }
17         }

3、許可權列表應該是某一個模組的許可權列表,因此,我們要接收一個模組ID的引數(如何傳遞的,待會再修改我們樹形選單的js,這裡先不管)

 1 /// <summary>
 2         /// 許可權管理 許可權列表
 3         /// </summary>
 4         /// <returns></returns>
 5         [UserAuthorizeAttribute(ModuleAlias = "Permission", OperaAction = "View")]
 6         public ActionResult Index()
 7         {
 8             try
 9             {
10                 //獲取模組ID
11                 var moduleId = Request.QueryString["moduleId"] ?? (Request["moduleId"] ?? "");
12 
13                 //如果模組ID不為空或NULL
14                 if(!string.IsNullOrEmpty(moduleId))
15                 {
16 
17                 }
18 
19                 return View();
20             }
21             catch (Exception e)
22             {
23                 WriteLog(Common.Enums.enumOperator.Select, "對模組許可權按鈕的管理載入主頁:", e);
24                 throw e.InnerException;
25             }
26         }

4、如果ID不為空或NULL 我們 模組資訊和模組的許可權列表 傳遞給檢視頁

 1         /// <summary>
 2         /// 許可權管理 許可權列表
 3         /// </summary>
 4         /// <returns></returns>
 5         [UserAuthorizeAttribute(ModuleAlias = "Permission", OperaAction = "View")]
 6         public ActionResult Index()
 7         {
 8             try
 9             {
10                 //獲取模組ID
11                 var moduleId = Request.QueryString["moduleId"] ?? (Request["moduleId"] ?? "");
12 
13                 //如果模組ID不為空或NULL
14                 if(!string.IsNullOrEmpty(moduleId))
15                 {
16                     //把模組ID轉為Int
17                     int module_Id = int.Parse(moduleId);
18 
19                     //模組資訊
20                     var module = this.ModuleManage.Get(p => p.ID == module_Id);
21 
22                     //繫結列表
23                     var query = this.PermissionManage.LoadAll(p => p.MODULEID == module.ID);
24 
25                     //關鍵字查詢
26                     if (!string.IsNullOrEmpty(keywords))
27                     {
28                         query = query.Where(p => p.NAME.Contains(keywords));
29                     }
30                     //輸出結果
31                     var result = query.OrderBy(p => p.SHOWORDER).ToList();
32 
33                     ViewBag.Search = base.keywords;
34 
35                     ViewBag.Module = module;
36 
37                     return View(result);
38                 }
39 
40                 return View();
41             }
42             catch (Exception e)
43             {
44                 WriteLog(Common.Enums.enumOperator.Select, "對模組許可權按鈕的管理載入主頁:", e);
45                 throw e.InnerException;
46             }
47         }

5、我們在檢視頁 輸出資訊 (注意一下,因為我們沒有新增初始化許可權的初始資料 所以 初始化許可權 按鈕是不展示的)

 1 @{
 2     Layout = "~/Views/Shared/_Layout.cshtml";
 3 }
 4 @model List<Domain.SYS_PERMISSION>
 5 <div class="wrapper wrapper-content  animated fadeInRight">
 6     <div class="row">
 7         <div class="col-sm-12">
 8             <div class="ibox float-e-margins">
 9                 <div class="ibox-title">
10                     @{
11                         if (ViewBag.Module != null)
12                         {
13                             Domain.SYS_MODULE module = ViewBag.Module as Domain.SYS_MODULE;
14                             if (module != null)
15                             {
16                                 <h5>@(module.NAME) - 許可權</h5>
17                                 @Html.Hidden("moduleId", module.ID)
18                                 @Html.Hidden("moduleType", module.MODULETYPE)
19                             }
20 
21                             <div class="ibox-tools">
22                                 <a class="btn btn-primary btn-xs p310" id="reset" action="reset"><i class="im-plus"></i> 初始化許可權</a>
23                                 <a class="btn btn-primary btn-xs p210" id="insert" action="add"><i class="fa fa-plus-circle fa-fw"></i> 建立新分類</a>
24                                 <a class="btn btn-warning btn-xs p210" id="modify" action="edit"><i class="fa fa-pencil fa-fw"></i> 編輯</a>
25                                 <a class="btn btn-danger btn-xs p210" id="delete" action="remove"><i class="fa fa-trash-o fa-fw"></i> 刪除</a>
26                                 <a class="reload-link" style="color: #c4c4c4" href="javascript:dig.reload()" data-toggle="tooltip" data-placement="left" title="重新整理">
27                                     <i class="fa fa-repeat fa-lg"></i>
28                                 </a>
29                             </div>
30                         }
31                         else
32                         {
33                             <h5>許可權管理</h5>
34                         }
35                     }
36                 </div>
37                 <div class="ibox-content">
38                     @using (Ajax.BeginForm("Index", null, new AjaxOptions() { }, new { @id = "form1", @class = "form-horizontal", @method = "get" }))
39                     {
40                         <div class="row">
41                             <div class="col-sm-9">
42                             </div>
43                             <div class="col-sm-3">
44                                 <div class="input-group">
45                                     @Html.TextBox("Search", null, new { @class = "input-sm form-control", @placeholder = "請輸入查詢關鍵詞" })
46                                     <span class="input-group-btn">
47                                         <button type="submit" onclick="submit()" class="btn btn-sm btn-primary"> 搜尋</button>
48                                     </span>
49                                 </div>
50                             </div>
51                         </div>
52                     }
53                     <div