特別聲明:
提供的源代碼已經包含了 AppBoxPro 的全部源代碼,用 VS2012 打開項目后,直接 Ctrl+F5 可以運行起來(默認使用VS自帶的LocalDB數據庫)。
FineUIPro是商業程序,僅包含v1.7.0公測版的DLL;當然你也可以自行把 FineUIPro 換成 FineUI(開源版),開源版下載地址。
AppBoxPro 是基於 FineUIPro 和 Entity Framework 的通用權限管理框架,包括用戶管理、職稱管理、部門管理、角色管理、角色權限管理等模塊。
之前我曾經寫過文章介紹AppBox,不過主要集中在 EntityFramework的使用上:
- AppBox_v2.0完整版免費下載,暨AppBox_v3.0正式發布!
- AppBox升級進行時 - 擁抱Entity Framework的Code First開發模式
- AppBox升級進行時 - 扁平化的權限設計
- AppBox升級進行時 - Entity Framework的增刪改查
- AppBox升級進行時 - 如何向OrderBy傳遞字符串參數(Entity Framework)
- AppBox升級進行時 - 關聯表查詢與更新(Entity Framework)
- AppBox升級進行時 - Attach陷阱(Entity Framework)
- AppBox升級進行時 - Any與All的用法(Entity Framework)
今天,除了公開 AppBoxPro 的最新源代碼外,我主要介紹下如果做到將權限控制到表格行內按鈕。
1. AppBox架構分析
AppBox中的權限管理涉及幾個概念:角色、用戶、權限、頁面
- 角色:用來對用戶進行分組,權限實際上是和角色對應的
- 用戶:一個用戶可以屬於多個角色
- 權限:頂級權限列表,比如“CoreDeptView”的意思是部門瀏覽權限,為了方便權限管理,我們還給權限一個簡單的分組
- 頁面:用戶操作的載體,一個頁面可以擁有多個權限,這個控制是在頁面代碼中進行的,主動權在頁面
用一張圖來概述這個架構:

2. 權限與頁面、角色的關系
2.1 權限與頁面:之前我們提到頁面擁有哪些權限,這個定義是在頁面代碼中的,而不是存在於數據庫中。
這就提供更大程序的靈活性,相當於每個頁面都可以從整個站點的權限集合中選擇自己需要的權限。
比如,部門列表頁面(dept.aspx),我們需要應用“部門瀏覽權限”,這個代碼是定義在 dept.aspx.cs 中的:
public partial class dept : PageBase
{
/// <summary>
/// 本頁面的瀏覽權限,空字符串表示本頁面不受權限控制
/// </summary>
public override string ViewPower
{
get
{
return "CoreDeptView";
}
}
由於“瀏覽權限”每個頁面都可能會用到,所以我們將處理“瀏覽權限”的代碼放在基類 PageBase.cs 中:
public class PageBase : System.Web.UI.Page
{
protected override void OnInit(EventArgs e)
{
base.OnInit(e);
// 此用戶是否有訪問此頁面的權限
if (!CheckPowerView())
{
CheckPowerFailWithPage();
return;
}
在 CheckPowerView 中,則需要拿到當前登陸用戶所屬的角色,然后查找此角色是否擁有 “CoreDeptView” 權限的定義:
/// <summary>
/// 檢查當前用戶是否擁有當前頁面的瀏覽權限
/// 頁面需要先定義ViewPower屬性,以確定頁面與某個瀏覽權限的對應關系
/// </summary>
/// <returns></returns>
protected bool CheckPowerView()
{
return CheckPower(ViewPower);
}
/// <summary>
/// 檢查當前用戶是否擁有某個權限
/// </summary>
/// <param name="powerType"></param>
/// <returns></returns>
protected bool CheckPower(string powerName)
{
// 如果權限名為空,則放行
if (String.IsNullOrEmpty(powerName))
{
return true;
}
// 當前登陸用戶的權限列表
List<string> rolePowerNames = GetRolePowerNames();
if (rolePowerNames.Contains(powerName))
{
return true;
}
return false;
}
還要注意一點:兩個頁面可能需要用到同一個權限
並且這個權限出現在頁面中的邏輯會截然不同,比如“CoreDeptEdit”權限(編輯部門):
在dept.aspx頁面,用來控制表格行內按鈕的啟用禁用狀態:
protected void Grid1_PreDataBound(object sender, EventArgs e)
{
// 數據綁定之前,進行權限檢查
CheckPowerWithWindowField("CoreDeptEdit", Grid1, "editField");
CheckPowerWithLinkButtonField("CoreDeptDelete", Grid1, "deleteField");
}

在dept_edit.aspx頁面,用來控制對此頁面的瀏覽權限:
public partial class dept_edit : PageBase
{
public override string ViewPower
{
get
{
return "CoreDeptEdit";
}
}

2.2 權限與角色:這個對應關系是定義在數據庫中的,相應的頁面操作界面如下所示。

3. 將權限控制到表格行內按鈕
經過上面的介紹,我們對AppBox中的權限控制有個大致的了解。
下面,我們通過一個小案例來介紹如何將權限控制到表格行內按鈕,還是以“CoreDeptEdit”這個權限為例。
3.1. 首先管理員(admin)登陸

3.2. 新建一個角色(測試角色)

3.3. 一個屬於本角色用戶(testuser)

3.4. 將 testuser 添加到測試角色
3.5. 為測試角色設置權限(注意,“編輯部門”權限沒有選中)

3.6. 用新創建的用戶 testuser 登陸

3.7. 新用戶 testuser 沒有編輯部門的權限

關鍵代碼(更加詳細的實現,請自行下載全部源代碼):
在 dept.aspx.cs 中:
public partial class dept : PageBase
{
protected void Grid1_PreDataBound(object sender, EventArgs e)
{
// 數據綁定之前,進行權限檢查
CheckPowerWithWindowField("CoreDeptEdit", Grid1, "editField");
在 PageBase.cs 中:
public class PageBase : System.Web.UI.Page
{
protected void CheckPowerWithWindowField(string powerName, FineUIPro.Grid grid, string columnID)
{
if (!CheckPower(powerName))
{
CheckPowerFailWithWindowField(grid, columnID);
}
}
protected void CheckPowerFailWithWindowField(FineUIPro.Grid grid, string columnID)
{
FineUIPro.WindowField btn = grid.FindColumn(columnID) as FineUIPro.WindowField;
btn.Enabled = false;
btn.ToolTip = CHECK_POWER_FAIL_ACTION_MESSAGE;
}
小結
AppBox的權限控制非常靈活和簡單,並且提供細粒度到頁面上的每個角落,不僅僅是頁面瀏覽、編輯、刪除、新增,甚至可以是某個特定按鈕的啟用禁用、某個DIV的顯示隱藏、某個面板的折疊展開,其實控制權就在你的手里面。
求推薦
如果本文對你有所啟發或者幫助,請點擊【推薦】按鈕,謝謝支持。
全部源代碼下載
http://yun.baidu.com/s/1gdAEOPd
