[Okta Webinar] Learn how to a build a cloud-first strategyRegister Now

x
?
Solved

Menu control with web.sitemap

Posted on 2006-06-02
5
Medium Priority
?
680 Views
Last Modified: 2012-06-27
Hi Experts

I have a menu control which at present i have hardcoded the different items.  I wanted to change this to either an XMLdatasource or SQLdatasource.

I have had a play with both but dont seem to be able to have more than one root node.
I want to have say five root nodes, then have a few nodes under them.

The web.sitemap seems to allow only one root node.....had a look around but everything i find has either one root node only or is hardcoded like mine.

I want to have a dynamic menu bar, at present i have hardcoded every option then disable the ones not needed for the user.  An idea i had was to return an XML source from a web service.....What do you think? Any links for doing something this this would be good.  No point i guess if the above is not possible.....

Thanks
Steve
0
Comment
Question by:osiris247
  • 2
  • 2
5 Comments
 
LVL 12

Accepted Solution

by:
deanvanrooyen earned 1500 total points
ID: 16815267
hi

if you are using .net2.0, then you can just put a treeview control or any nav control on the page, add a Web.sitemap, and then a SiteMapDataSource control, then set the treeview datasource to the SiteMapDataSource.  then in the SiteMapDataSource properties set the showstartingnode to false and it will only show the parent nodes and not the root node from the Web.sitemap

I believe the root node is an xml specification and any xml doc can only have 1 root node.
0
 
LVL 7

Author Comment

by:osiris247
ID: 16815333
Thanks....that is exactly what i wanted for the menu.  XML docs can only have one root node, i didnt spot that property!!

Just the dynamic thing to work on now....

Any links??

Steve
0
 
LVL 7

Expert Comment

by:levyuk
ID: 16815441
You can use multiple sitemaps and change the sitemap for the individual user. I tried this once and it worked ok. There is some info on it here

http://www.levyuk.f2s.com/aspnet_sitemaps.php
0
 
LVL 7

Author Comment

by:osiris247
ID: 16815457
thats ok but not dynamic enough.....

consider over 20 menu options....each user potentially different.  I do have user roles (custom not asp way) but this can be customised to break the generic set.

i have the permissions in SQL2005 database, flag for each option on the menu.  I need to either loop though enabling the correct node (doing at the mo) but i would like to not even show the nodes of the sitemap that the user doesnt have permission to use.



Steve
0
 
LVL 12

Expert Comment

by:deanvanrooyen
ID: 16826633
hi,

i do a similar thing with mysql.

I have a table called roles and a table called userinroles.

i am a newbie c# programmer, i have decided to use a method of creating roles that match the page name. therefore there is a role called mainportal.aspx, when the mainportal.aspx page loads it checks if the user is in the role of mainportal.aspx and if not then direct to a generic page. I have used roles as i have a page that allows admin users to select a system user and use a check box next to each role to select if they can "see" a page or not.

i use one master page the houses a treeview for navigation.

these are my steps - performed on every page load of EACH aspx page.

1 - check if the user is a system user (in role "SystemUser"), if not direct them out of the system

CheckNavigation(Session["loginname"].ToString(), "SystemUser");

   public  void CheckNavigation(string username, string rolename)
    {
        if (!IsUserInRole(username, rolename.ToLower())) //this will call a stored procedure to check if the record exists in the db
        {
            Server.Transfer("~/secure/content/Blank.aspx");
        }

    }

2 - get the name of the current executing page and check if the user is in that role - if not redirect them
//get the page name
        int start = HttpContext.Current.Request.CurrentExecutionFilePath.LastIndexOf('/') + 1;
        int lenght = HttpContext.Current.Request.CurrentExecutionFilePath.Length - start;
        string fileaspx = HttpContext.Current.Request.CurrentExecutionFilePath.Substring(start, lenght);
CheckNavigation(Session["loginname"].ToString(), fileaspx);

3 - manipulate the treeview, check each nodes aspx page and if the user is not in that "role" then remove the node from the treeview.
I found that this method below worked ok if called in the aspx page OnPreRenderComplete, because the treeview binding takes place after the page load is called as I used a sitemap and the binding is automatic. so if i tried to remove nodes in the page_load, the treeview would not be effected when the page loaded as the binding to the sitemap occured after the page_load occured.

CheckTreeLinks(Master, Session["loginname"].ToString()); // this is called in the aspx page so pass ref to master page for access to the treeview

the below is my main method of removing the treenodes. this should be redone with a better recursive method of itterating through the treenode collection of every treenode - that means that off the root note you have parent nodes, each parent node might have a few nodes below it,which inturn becomes like a sub parent node if it has child nodes below it. Another issue I found here is that when I used an Enumerator to go through the collection, i could not remove the node while in the while loop moving through the enumerator - this causes an error. so what I did was use an array to store the index of the nodes to remove and then go back through the parent level (2cnd level) and remove the nodes. then i do the same thing again with each parent nodes child nodes and do the check. I am aware that there are better ways of doing this but I just didnt have the time to do the research. i believe ther is a sitemapprovider class that can do this sort of functionality - not sure though. I want a better way of looping through every node in the treeview and just removing the node nice an cleanly, let me know if you find it....

using ...
using System.Collections;
using System.Collections.Specialized;

    ArrayList iremove; //array for index of removing nodes

    public void CheckTreeLinks(MasterPage mp,string username)
    {
            //index 0 = root node - home
            //index 1 = childnode       |__ calls
            //index 2 =                      |__news

            //check and modify treeview nav links
            // get ref to treeview

            TreeView myTV = (TreeView)mp.FindControl("TreeViewNav");
            TreeNodeCollection myNodeCollection = myTV.Nodes[0].ChildNodes;

            // Create an enumerator for the collection.
            IEnumerator myEnumerator = myNodeCollection.GetEnumerator();

            //get user roles
            string[] userroles = GetRolesForUser(username);

            //check all top level links
            //check if system user first
            if (!IsRoleInArray("SystemUser", userroles))
                myTV.Nodes.RemoveAt(0); //remove all links
            else //user can login so check sub links off root
            {
                int x = 0; // x holds index to remove treenode
                while (myEnumerator.MoveNext())
                {
                    try
                    {
                        //use the filename.aspx as the role check
                        string [] file = ((TreeNode)myEnumerator.Current).DataPath.Split('/');
                        if (!IsRoleInArray(file[file.Length -1], userroles))
                        {
                            iremove.Add(x);
                        }
                    }
                    catch (Exception e)
                    {
                        throw (e);
                    }
                    x++;
                }

                //remove links at specific index's stored in the iremove array.
                int[] check = (int[])iremove.ToArray(typeof(int)); //create int array easier to use below
                int index = 0;
                int c = 0;
                for (int i = 0; i < iremove.Count; i++)
                {
                    index = check[i];
                    myTV.Nodes[0].ChildNodes.RemoveAt(index - c);
                    c++;
                }

                //do sub links/ parent child nodes
                //remove the second level nodes
                //this is a temporary solution  for now to remove second level nodes(parent child nodes) and is different to the above method
                //start at the last node and move backwards when removing,this works and doesnt cause the enumerator to error out

                TreeNodeCollection myNodeCollection2 = myTV.Nodes[0].ChildNodes;

                // Create an enumerator for the collection.
                IEnumerator myEnumerator2 = myNodeCollection2.GetEnumerator();

                while (myEnumerator2.MoveNext())
                {
                    try
                    {

                        for (int n = ((TreeNode)myEnumerator2.Current).ChildNodes.Count - 1; n > -1; n--)
                        {
                            string[] file2 = ((TreeNode)myEnumerator2.Current).ChildNodes[n].DataPath.Split('/');
                            if (!IsRoleInArray(file2[file2.Length -1], userroles))
                            {
                                ((TreeNode)myEnumerator2.Current).ChildNodes.RemoveAt(n);

                            }
                        }
                    }
                    catch (Exception e)
                    {
                        throw (e);
                    }
               
                }

            }//else

    }
                           




0

Featured Post

Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

In this Article, I will provide a few tips in problem and solution manner. Opening an ASPX page in Visual studio 2003 is very slow. To make it fast, please do follow below steps:   Open the Solution/Project. Right click the ASPX file to b…
Today is the age of broadband.  More and more people are going this route determined to experience the web and it’s multitude of services as quickly and painlessly as possible. Coupled with the move to broadband, people are experiencing the web via …
This lesson discusses how to use a Mainform + Subforms in Microsoft Access to find and enter data for payments on orders. The sample data comes from a custom shop that builds and sells movable storage structures that are delivered to your property. …
Look below the covers at a subform control , and the form that is inside it. Explore properties and see how easy it is to aggregate, get statistics, and synchronize results for your data. A Microsoft Access subform is used to show relevant calcul…
Suggested Courses
Course of the Month19 days, 11 hours left to enroll

872 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question