Click here to Skip to main content
15,896,526 members

TODODotNet - Professional Profile



Summary

    Blog RSS
3,066
Author
5
Authority
2
Debator
5
Editor
202
Participant
0
Enquirer
0
Organiser
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Reputation

Weekly Data. Recent events may not appear immediately. For information on Reputation please see the FAQ.

Privileges

Members need to achieve at least one of the given member levels in the given reputation categories in order to perform a given action. For example, to store personal files in your account area you will need to achieve Platinum level in either the Author or Authority category. The "If Owner" column means that owners of an item automatically have the privilege. The member types column lists member types who gain the privilege regardless of their reputation level.

ActionAuthorAuthorityDebatorEditorEnquirerOrganiserParticipantIf OwnerMember Types
Have no restrictions on voting frequencysilversilversilversilver
Bypass spam checks when posting contentsilversilversilversilversilversilvergoldSubEditor, Mentor, Protector, Editor
Store personal files in your account areaplatinumplatinumSubEditor, Editor
Have live hyperlinks in your profilebronzebronzebronzebronzebronzebronzesilverSubEditor, Protector, Editor
Have the ability to include a biography in your profilebronzebronzebronzebronzebronzebronzesilverSubEditor, Protector, Editor
Edit a Question in Q&AsilversilversilversilverYesSubEditor, Protector, Editor
Edit an Answer in Q&AsilversilversilversilverYesSubEditor, Protector, Editor
Delete a Question in Q&AYesSubEditor, Protector, Editor
Delete an Answer in Q&AYesSubEditor, Protector, Editor
Report an ArticlesilversilversilversilverSubEditor, Mentor, Protector, Editor
Approve/Disapprove a pending ArticlegoldgoldgoldgoldSubEditor, Mentor, Protector, Editor
Edit other members' articlesSubEditor, Protector, Editor
Create an article without requiring moderationplatinumSubEditor, Mentor, Protector, Editor
Approve/Disapprove a pending QuestionProtector
Approve/Disapprove a pending AnswerProtector
Report a forum messagesilversilverbronzeProtector, Editor
Approve/Disapprove a pending Forum MessageProtector
Have the ability to send direct emails to members in the forumsProtector
Create a new tagsilversilversilversilver
Modify a tagsilversilversilversilver

Actions with a green tick can be performed by this member.


 
GeneralMVC SQL Site Map Provider Pin
TODODotNet11-Jan-09 23:33
TODODotNet11-Jan-09 23:33 
You can download the sample here[^].
I’m developing my first MVC application. I’ve been working with ASP.Net for a couple of years and only now I’ve some contact with MVC.

First of all, I’ve defined the application layout and I realized that I needed to display the menu and the site map path dynamically. After some research I couldn’t find any SQL site map provider for MVC. The only sample that I’ve found was the MVCSiteMapProvider, which has XML as data source, posted by Maarten Balliauw. With this sample I’ve developed the MVCSQLSiteMapProvider. This is only a prototype and it could be improved. I’ve only implemented the base functionalities that I needed so far. So if you have any suggestion, just write them down.

The site map data model is similar with the XML site map provider. So it’s possible to define a node with the correspondent URL or with the controller/action.

image[^]

The site pap provider class inherits from the StaticSiteMapProvider and, as I said before, I’ve only implemented what I needed so far.

public class MvcSQLSitemapProvider : StaticSiteMapProvider
    {
        private const string _errormsg1 = "Missing node ID";
        private const string _errormsg2 = "MDuplicate node ID";
        private const string _errormsg3 = "Missing parent ID";
        private const string _errormsg4 = "Invalid parent ID";
        private const string _errormsg5 = "Empty or missing connection string";
        private const string _errormsg6 = "Missing connection string";
        private const string _errormsg7 = "Empty connection string";
        private string _connect = String.Empty;
        private Dictionary _nodes = new Dictionary(16);
        private SiteMapNode _root;
        public override void Initialize(string name, NameValueCollection attributes)
        {
            if (attributes == null)
                throw new ArgumentNullException("attributes");
            if (string.IsNullOrEmpty(name))
                name = "MvcSitemapProvider";
            if (string.IsNullOrEmpty(attributes["description"]))
            {
                attributes.Remove("description");
                attributes.Add("description", "MVC site map provider");
            }
            base.Initialize(name, attributes);
            string connect = attributes["connectionStringName"];
            if (string.IsNullOrEmpty(connect))
                throw new ProviderException(_errormsg5);
            attributes.Remove("connectionStringName");
            if (WebConfigurationManager.ConnectionStrings[connect] == null)
                throw new ProviderException(_errormsg6);
            _connect = WebConfigurationManager.ConnectionStrings[connect].ConnectionString;
            if (string.IsNullOrEmpty(_connect))
                throw new ProviderException(_errormsg7);
            if (attributes.Count > 0)
            {
                string attr = attributes.GetKey(0);
                if (!string.IsNullOrEmpty(attr))
                    throw new ProviderException(string.Format("Unrecognized attribute: {0}", attr));
            }
        }
        public override SiteMapNode BuildSiteMap()
        {
            lock (this)
            {
                if (_root != null)
                    return _root;
                SiteMapContextDataContext db = new SiteMapContextDataContext(_connect);
                var siteMpaQuery = from s in db.SITEMAPs
                                   orderby s.ID
                                   select s;
                foreach (var item in siteMpaQuery)
                {
                    if (item.Equals(siteMpaQuery.First()))
                    {
                        _root = CreateSiteMapFromRow(item);
                        AddNode(_root, null);
                    }
                    else
                    {
                        SiteMapNode node = CreateSiteMapFromRow(item);
                        AddNode(node, GetParentNodeFromNode(item));
                    }
                }
                return _root;
            }
        }
        private SiteMapNode CreateSiteMapFromRow(SITEMAP item)
        {
            if (_nodes.ContainsKey(item.ID))
                throw new ProviderException(_errormsg2);
            SiteMapNode node = new SiteMapNode(this, item.ID);
            if (!string.IsNullOrEmpty(item.URL))
            {
                node.Title = string.IsNullOrEmpty(item.TITLE) ? null : item.TITLE;
                node.Description = string.IsNullOrEmpty(item.DESCRIPTION) ? null : item.DESCRIPTION;
                node.Url = string.IsNullOrEmpty(item.URL) ? null : item.URL;
            }
            else
            {
                node.Title = string.IsNullOrEmpty(item.TITLE) ? null : item.TITLE;
                node.Description = string.IsNullOrEmpty(item.DESCRIPTION) ? null : item.DESCRIPTION;
                IDictionary routeValues = new Dictionary();
                if (string.IsNullOrEmpty(item.CONTROLLER))
                    routeValues.Add("controller", "Home");
                else
                    routeValues.Add("controller", item.CONTROLLER);
                if (string.IsNullOrEmpty(item.CONTROLLER))
                    routeValues.Add("action", "Index");
                else
                    routeValues.Add("action", item.ACTION);
                if (!string.IsNullOrEmpty(item.PARAMID))
                    routeValues.Add("id", item.PARAMID);
                HttpContextWrapper httpContext = new HttpContextWrapper(HttpContext.Current);
                RouteData routeData = RouteTable.Routes.GetRouteData(httpContext);
                if (routeData != null)
                {
                    VirtualPathData virtualPath = routeData.Route.GetVirtualPath(new RequestContext(httpContext, routeData), new RouteValueDictionary(routeValues));
                    if (virtualPath != null)
                    {
                        node.Url = "~/" + virtualPath.VirtualPath;
                    }
                }
            }
            _nodes.Add(item.ID, node);
            return node;
        }
        private SiteMapNode GetParentNodeFromNode(SITEMAP item)
        {
            if (!_nodes.ContainsKey(item.PARENT_ID))
                throw new ProviderException(_errormsg4);
            return _nodes[item.PARENT_ID];
        }
        protected override SiteMapNode GetRootNodeCore()
        {
            return BuildSiteMap();
        }
    }


I’ve also created 3 user controls. The first one is used to display the main menu. It retrieves all the root child nodes and displays them.

image[^]

The second one retrieves the site map path to the current page.

image[^]

The last control is used to display the content menu, which retrieves all the current node child nodes.

image[^]

These controls are very simple and I didn’t took much time on making them good looking. Smile | :)
Well, I hope this post was useful.

You can download the sample here[^].

TODO

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

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