Dynamic to generate menu items with MVCSiteMapProvider

Introduction

The MVCSiteMapProvider is powerful and can generate the site map menu from xml, but sometime you may want to dynamic to generate the menu by user access rights, in this time we can use the dynamicNodeProvider for thatUse the code

Using the code

1.Create a custom SiteMapProvider and implement the IDynamicNodeProvider interface

public class CoderBlogSiteMapProvider : IDynamicNodeProvider
{
     public  IEnumerable<DynamicNode> GetDynamicNodeCollection(ISiteMapNode nodes)
     {
         var returnValue = new List<DynamicNode>();         

         return returnValue;
     }  

     public bool AppliesTo(string providerName)
     {
         if (string.IsNullOrEmpty(providerName))
             return false;
         return GetType() == Type.GetType(providerName, false);
     }
}

2. In the GetDynamicNodeCollection method, you can check the access righs and get current menu items and create the dynamic node

//get the pages by access right
var pageIds = CoderBlogAccessRight.GetAccessPageIds(db);
var accessMmenus = db.Query<ACCESS_RIGHT_Page>("Select * from ACCESS_RIGHT_Page where PageId in @pageIds order by DisplayPriority ", new { pageIds = pageIds });
foreach (var page in accessMmenus)
{
    //create the dynamic node for site map
    DynamicNode node = new DynamicNode()
    {
        // menu title
        Title = page.Name,
        // parent page id
        ParentKey = page.ParentId.HasValue ? page.ParentId.Value.ToString() : "",
        // Node Key
        Key = page.PageId.ToString(),
        // Action Name
        Action = page.Action,
        // Controller Name
        Controller = page.Controller,
        // Url (if not null will use this url replace to controller and action)
        Url = page.Url,
        // If set the url to # then just not can click
        Clickable = page.Url != "#"
    };
    if (!string.IsNullOrWhiteSpace(page.RouteValues))
    {
        // get the RouteValues 
        // ex. Key1=value1,Key2=value2...
        node.RouteValues = page.RouteValues.Split(',').Select(value => value.Split('='))
                                .ToDictionary(pair => pair[0], pair => (object)pair[1]);
    }
    node.Attributes.Add("visibility", page.IsActive ? "" : "!MenuHelper");
    returnValue.Add(node);
}

3. The full source code should be as below

namespace CoderBlog
{
    public class CoderBlogSiteMapProvider : IDynamicNodeProvider
    {
        public  IEnumerable<DynamicNode> GetDynamicNodeCollection(ISiteMapNode nodes)
        {
            var returnValue = new List<DynamicNode>();
            //check whether the user has been login
            if (CoderBlogSession.Instance.UserInfo != null)
            {
                using (var db = DBService.Connection)
                {
                    //get the page id by access rights
                    var pageIds = CoderBlogAccessRight.GetAccessPageIds(db);
                    var accessMmenus = db.Query<ACCESS_RIGHT_Page>("Select * from ACCESS_RIGHT_Page where PageId in @pageIds order by DisplayPriority ", new { pageIds = pageIds });
                    foreach (var page in accessMmenus)
                    {
                        DynamicNode node = new DynamicNode()
                        {
                            // menu title
                            Title = page.Name,
                            // parent page id
                            ParentKey = page.ParentId.HasValue ? page.ParentId.Value.ToString() : "",
                            // Node Key
                            Key = page.PageId.ToString(),
                            // Action Name
                            Action = page.Action,
                            // Controller Name
                            Controller = page.Controller,
                            // Url (if not null will use this url replace to controller and action)
                            Url = page.Url,
                            // If set the url to # then just not can click
                            Clickable = page.Url != "#"
                        };
                        if (!string.IsNullOrWhiteSpace(page.RouteValues))
                        {
                            // get the RouteValues 
                            // ex. Key1=value1,Key2=value2...
                            node.RouteValues = page.RouteValues.Split(',').Select(value => value.Split('='))
                                                    .ToDictionary(pair => pair[0], pair => (object)pair[1]);
                        }
                        node.Attributes.Add("visibility", page.IsActive ? "" : "!MenuHelper");
                        returnValue.Add(node);
                    }
                }
            }
            
            return returnValue;
        }

        public bool AppliesTo(string providerName)
        {
            if (string.IsNullOrEmpty(providerName))
                return false;
            return GetType() == Type.GetType(providerName, false);
        }
    }
}

4. Add the dynamicNodeProvider attribute in Mvc.sitemap file

<mvcSiteMapNode title="Home"  controller="Home" action="Index">
    <mvcSiteMapNode title="Menu" dynamicNodeProvider="CoderBlog.CoderBlogSiteMapProvider, CoderBlog"/>
</mvcSiteMapNode>

After that, you will find the site map menu dynamic generate by difference user rols!

5,051 total views, 9 views today

Share your vote!


Do you like this post?
  • Fascinated
  • Happy
  • Sad
  • Angry
  • Bored
  • Afraid

You may also like...

shares