65.9K
CodeProject 正在变化。 阅读更多。
Home

根据用户权限从数据库生成菜单

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.97/5 (22投票s)

2012 年 9 月 25 日

CPOL

3分钟阅读

viewsIcon

131866

downloadIcon

5663

根据用户权限从数据库动态生成菜单。

引言

此菜单旨在配合用户权限使用。导航是网站的重要组成部分。它是访问者导航到我们网站主要区域的方式,使他们能够轻松找到您的优质内容。如果根据用户权限从数据库完成,这对于网站来说是一个加分项。

本文将解释“我们如何根据网站管理员提供的用户权限从数据库生成菜单”

前端演示 

但是,生成菜单的前端部分将与从数据库生成菜单类似。在这里,我将修改后端部分,并仅从那里生成项目。

在进入后端之前,让我们先了解一些关于从数据库生成菜单的基础知识。在这里,在创建此菜单时,我使用了一些基本功能,例如

从数据库获取菜单数据 

我使用此功能来获取特定用户的菜单项(这里我硬编码了 UserID K010。您可以在此处设置会话值)。  

private DataTable GetMenuData()
{
    try
    {
        using (SqlConnection con = new SqlConnection(
          ConfigurationManager.ConnectionStrings["MenuWithCustomPrivs"].ConnectionString))
        {
            SqlCommand cmd = new SqlCommand("spMenuItem", con);
            cmd.CommandType = CommandType.StoredProcedure;
            cmd.Parameters.AddWithValue("@UserID", "K010");
            //K010 : Here I hardcoded the UserID. You can set your session's value UserID
            DataTable dtMenuItems = new DataTable();
            SqlDataAdapter sda = new SqlDataAdapter(cmd);
            sda.Fill(dtMenuItems);
            cmd.Dispose();
            sda.Dispose();
            return dtMenuItems;
        }
    }
    catch (Exception ex) {
        //Show the error massage here
    }
    return null;
}

添加顶级/父级菜单项 

在这里,通过这段代码,我将添加 Parent IDNULL 的菜单项。 并且我们还将调用函数来绑定子菜单。 在此函数中,我将调用另一个函数 AddChildMenuItems,该函数将绑定该菜单项的子项。

private void AddTopMenuItems(DataTable menuData)
{
      DataView view = null;
      try
      {
          view = new DataView(menuData);
          view.RowFilter = "ParentID IS NULL";
          foreach (DataRowView row in view)
          {
               //Adding the menu item
               MenuItem newMenuItem = new MenuItem(row["Text"].ToString(), row["MenuID"].ToString());
               menuBar.Items.Add(newMenuItem);
               //Calling the function to add the child menu items
               AddChildMenuItems(menuData, newMenuItem);
          }
      }
      catch (Exception ex)
      {
          //Show the error massage here
      }
      finally {
            view = null;
      }
}

添加子菜单项 

在这里,我使用这段代码来绑定菜单中的子项。 我在这里根据从上面的函数传递的父 ID 过滤菜单项。

private void AddChildMenuItems(DataTable menuData, MenuItem parentMenuItem)
{
    DataView view = null;
    try
    {
        view = new DataView(menuData);
        view.RowFilter = "ParentID=" + parentMenuItem.Value;
        foreach (DataRowView row in view)
        {
            MenuItem newMenuItem = new MenuItem(row["Text"].ToString(), row["MenuID"].ToString());
            newMenuItem.NavigateUrl = row["NavigateUrl"].ToString();
            parentMenuItem.ChildItems.Add(newMenuItem);
            // This code is used to recursively add child menu items filtering by ParentID
            AddChildMenuItems(menuData, newMenuItem);
        }
    }
    catch (Exception ex)
    {
        //Show the error massage here
    }
    finally
    {
        view = null;
    }
}

因此,这实际上是绑定菜单控件的基本功能。

后端演示 

现在,回到重点,数据库结构,在这里我将有五个不同的表,其中包含有关用户、组(角色)、其权限和菜单项的详细信息。

  1. tblGroupPrivMst:此表包含有关组/角色以及适用于该角色的权限位的相关信息。
  2. tblMenuMst:此表包含菜单描述、菜单 ID 和导航 URL 字段。
  3. tblUserGrpMap: 这是一个映射表,它将处理用户与相应组的关系。 
  4. tblDesgMst:此表包含网站下用户的职位。
  5. tblUserMst:此表包含用户的详细信息。

角色的权限位将存储在表 tblGroupPrivMst 中,并且权限位的长度将等于菜单项的总长度。这些权限位只不过是 01 位的组合。假设,菜单项总数为 10,则权限位为 0101011100 ,并将以这样的方式排列,以便菜单项将与位位置连续。这里的第一个位置为 0,表示第一个位置的项目将不适用于该角色。 

生成菜单

您可能会喜欢编写简单的 SQL 存储过程来生成菜单。 我用来根据用户权限生成菜单项的存储过程如下

CREATE PROCEDURE [dbo].[spMenuItem]
    @UserID [varchar](50)
WITH EXECUTE AS CALLER
AS
BEGIN
    --DECLARE @GroupCode VARCHAR(5)
    --SET @GroupCode=(SELECT DISTINCT GroupCode FROM tblUserGrpMap WHERE UserID=@UserID)
    CREATE TABLE #TMP(MenuID INT, Text VARCHAR(50), Description VARCHAR(50), ParentID INT, NavigateUrl VARCHAR(100))
    DECLARE @VAL VARCHAR(MAX), @Pos INT, @len INT
    SET @VAL=(SELECT REPLACE(REPLACE(CONVERT(VARCHAR(30), SUM(CAST(PrivilegeID AS 
        NUMERIC(30, 0)))), '2', '1'), '3', '1') FROM tblGroupPrivMst WHERE GroupCode 
        in (SELECT GroupCode FROM tblUserGrpMap WHERE UserID=@UserID))
    SET @Pos=1
    SET @len=LEN(@VAL)
    WHILE(@len!=0)
    BEGIN
        DECLARE @Value CHAR(1)
        SET @Value=SUBSTRING(@VAL, @Pos, 1)
        IF @Value=1
        BEGIN
            --PRINT @Value
            INSERT INTO #TMP SELECT * FROM tblMenuMst WHERE MenuID=@Pos
        END
        SET @Pos=@Pos+1
        SET @len=@len-1
    END
    --For first Node (Inserting The Parent Node)
    INSERT INTO #TMP SELECT * FROM tblMenuMst WHERE MenuID IN(SELECT DISTINCT 
      ParentID FROM #TMP WHERE ParentID NOT IN(SELECT MenuID FROM #TMP))
    --For second Node (Inserting The Parent Node)
    INSERT INTO #TMP SELECT * FROM tblMenuMst WHERE MenuID IN(SELECT DISTINCT 
      ParentID FROM #TMP WHERE ParentID NOT IN(SELECT MenuID FROM #TMP))
    --For third Node (Inserting The Parent Node)
    INSERT INTO #TMP SELECT * FROM tblMenuMst WHERE MenuID IN(SELECT DISTINCT 
      ParentID FROM #TMP WHERE ParentID NOT IN(SELECT MenuID FROM #TMP))
    SELECT * FROM #TMP ORDER BY MenuID ASC
    DROP TABLE #TMP
END

此存储过程将生成最多三级的菜单项。 如果您有更多级别,则需要重复此插入命令

INSERT INTO #TMP SELECT * FROM tblMenuMst WHERE MenuID IN(SELECT DISTINCT ParentID FROM #TMP WHERE ParentID NOT IN(SELECT MenuID FROM #TMP)) 

输出    

运行程序后,您将获得类似这样的菜单

我知道,我在设计方面很无聊。 

您可以使用 Sql Update Command 更新用户的权限,或者您也可以创建一个用于更新用户权限的屏幕。  在后面的部分,我将尝试涵盖所有内容,例如,为用户分配菜单权限,将用户与多个角色映射。

终点

我希望这篇文章对您有所帮助。 

感谢您抽出宝贵时间阅读本文。 欢迎提出任何建议和指导。

© . All rights reserved.