Permissions and Levels in ASP:Menu






4.86/5 (12 votes)
Setting permissions to certain menuitems according to logged in user on the fly.
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:
- The
ValuePath
of theMenuItem
, and - The
MaximumDynamicDisplayLevels
property of theMenu
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 MenuItem
s are as follows:
MenuItem Value
ParentItem1 p1
SubMenuItem2 s1
SubSubItem1 ss1
SSubItem1 sss1
Then the value path of the above MenuItem
s 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:
- When we set it to 1
- And when we set it to 2:
menuBar.MaximumDynamicDisplayLevels = 1;
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
- In the attached source code I have provided a page named UserPermissions.aspx which you can use to assign permissions with ease.
- I have kept the database structures and sample data from tables for reference.