Click here to Skip to main content
Click here to Skip to main content

Permissions and Levels in ASP:Menu

By , 17 Apr 2012
Rate this:
Please Sign up or sign in to vote.

Introduction

In my last article I had discussed how to generate a menu dynamically from the database. In this article you will see how to generate a menu with two or more levels and deny access to certain menu items at runtime based on user permissions set by the administrator.

So let's design a multiple level menu first and for that we need to keep in mind two things:

  1. The ValuePath of the MenuItem, and
  2. The MaximumDynamicDisplayLevels property of the Menu control.

The ValuePath  

The ValuePath property contains the location of a particular menu item with respect to its parents, their parents, and so on, e.g., consider the following screenshot:

 

If the Value property of the MenuItems are as follows:  

MenuItem	Value
ParentItem1	p1
SubMenuItem2	s1
SubSubItem1	ss1
SSubItem1	sss1

Then the value path of the above MenuItems would be as follows:

MenuItem	ValuePath
ParentItem1	p1
SubMenuItem2	p1/s1
SubSubItem1	p1/s1/ss1
SSubItem1	p1/s1/ss1/sss1

The getValuePath function in the attached code calculates and returns the valuepath of a MenuItem using its assigned MenuID and MenuItemCollection from the database:

private string getValuePath(Int32 Parent, DataTable dt)
{
    int predecessor = Parent;
    StringBuilder valuePath = new StringBuilder();
    valuePath.Append(Parent.ToString());
    DataRow[] drPar;
    while (true)
    {
        drPar = dt.Select("MenuID=" + predecessor);
        if (drPar[0]["ParentID"].ToString().Equals("0"))
            break;
        valuePath.Insert(0,'/');
        valuePath.Insert(0,drPar[0]["ParentID"].ToString());
        predecessor = Convert.ToInt32(drPar[0]["ParentID"].ToString());
    }
    return valuePath.ToString();
}

Menu Levels

You can control the Maximum Display Levels (i.e., Menu Depth) of the Menu by adding a Line in the Page_load event of the master page when !IsPostBack, like:

menuBar.MaximumDynamicDisplayLevels = 3;
Menu Levels in Action:
  1. When we set it to 1
  2. menuBar.MaximumDynamicDisplayLevels = 1;

  3. And when we set it to 2:
  4. 	menuBar.MaximumDynamicDisplayLevels = 2;

    As you can see, the display levels of a menu depend on the user-setting irrespective of how much levels you have created in the database.

Creating a menu with multiple levels

To generate a Menu with more than one levels you would need to know the valuepath of the MenuItem to whom you are going to add a child. The following code snippet is the replacement of the getMenu() function used in the previous article:

foreach (DataRow dr in dt.Select("ParentID >" + 0))
{
    MenuItem mnu = new MenuItem(dr["MenuName"].ToString(), dr["MenuID"].ToString(),
	"", dr["MenuLocation"].ToString());

    //Code for Multiple Menu Levels
    string valuePath = getValuePath(Convert.ToInt32(dr["ParentID"].ToString()),dt);
    menuBar.FindItem(valuePath).ChildItems.Add(mnu);
    //End Code for Multiple Menu Levels
}

The first line enclosed in comments gets the ValuePath of a MenuItem.

While the second line uses this retrieved ValuePath to find the MenuItem from MenuItemsCollection and adds the MenuItem mnu to it as child.

Breakpoint: So till now we have created a menu with more than just one level and now we will assign permissions to the menu items by referring userpermissions from database. 

Menu Permissions

Before going further I must tell you that I have stored the permissions as string under a column named permissions in the user table in following format

1-11-12-

where menu IDs that are allowed for the corresponding user are separated by '-'.

Applying Permissions of a user to the menu is pretty simple.

Step 1: Retrieve the permissions string from database using the getUserPermissions(string username) function and split the returned string into an array of permitted MenuIDs

if (Session["username"] == null)
{
    return;
}
String[] permissions = getUserPermissions(Session["username"].ToString()).Split('-');

Here the getUserPermissions(string username) function takes logged in username as its argument and returns the corresponding permissions string which is then split at '-'s and stored inside an string array.

Step 2: Now that you have at hand the permissions, just toggle the MenuItem.Enabled property of sub menu items from inside the loop that adds submenu items, according to its presence in the permissions array.

if (!permissions.Contains(dr["MenuID"].ToString()))
{
      mnu.Enabled = false;
      mnu.ImageUrl = "denied.png";
}
else
{
      mnu.Enabled = true;
}

That's it, done. Below is a screenshot that shows a menu that is shown to a user who has some restrictions

Url Validation

You may ask what if the user directly types the url in the address bar and opens the page, not bothering whether the menuitem referring to that page is disabled or not. In that case the method validateurl(string url) that I have designed to check whether the page url being addressed is permitted or not.

...
DataRow[] drValidUrl = dt.Select("MenuLocation like '%" + url + "%'");
if (!(drValidUrl.Length == 0))
{
    String[] permissions = getUserPermissions(Session["username"].ToString()).Split('-');
    if (!permissions.Contains(drValidUrl[0]["MenuID"].ToString()))
    {
        Response.Redirect("~/Denied.htm");
    }
}
...

The above snippet is a portion of the validateurl(string url) method that takes as its argument the absolute path of the URL being requested.

this.Request.Url.AbsolutePath
and checks whether the URLs corresponding menu ID is present in the permissions array or not. If not then the user is greeted with following page..

Using the code

  1. In the attached source code I have provided a page named UserPermissions.aspx which you can use to assign permissions with ease.
  2. I have kept the database structures and sample data from tables for reference.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

Prabhat Spark
Software Developer Digital Avenues Ltd.
India India
I'm a ASP.NET and C# programmer with interests in playing games such as Unreal Tournament, FIFA and listening to rap music that have meaningful lyrics...Smile | :)
Follow on   Twitter

Comments and Discussions

 
GeneralMy vote of 5 PinmemberDebopam Pal18-Nov-13 8:38 
QuestionThanks a Million for an Excellent code Pinmembergetvinay19888-May-13 2:14 
Questionaa Pinmembergaurav112217-Apr-13 18:54 
Questionasp.net Pinmemberrimjhim_43-Oct-12 1:45 
QuestionObject reference doesnot set to instance of object [modified] PinmemberKarthik Reddy9-Sep-12 23:13 
SuggestionRe: Object reference doesnot set to instance of object PinmemberPrabhat Kr. Singh14-Sep-12 6:02 
GeneralRe: Object reference doesnot set to instance of object PinmemberKarthik Reddy17-Sep-12 0:26 
QuestionGood Job!!! Pinmemberernestmachado19-Jun-12 1:00 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web01 | 2.8.140421.2 | Last Updated 17 Apr 2012
Article Copyright 2012 by Prabhat Spark
Everything else Copyright © CodeProject, 1999-2014
Terms of Use
Layout: fixed | fluid