MvcSiteMapProvider 2.2.0 released

I’m proud to announce that MvcSiteMapProvider 2.2.0 has just been uploaded to CodePlex. It should also be available through NuPack in the coming hours. This release has taken a while, but that’s because I’ve been making some important changes...

MvcSiteMapProvider is, as the name implies, an ASP.NET MVC SiteMapProvider implementation for the ASP.NET MVC framework. Targeted at ASP.NET MVC 2, it provides sitemap XML functionality and interoperability with the classic ASP.NET sitemap controls, like the SiteMapPath control for rendering breadcrumbs and the Menu control.

In this post, I’ll give you a short update on what has changed as well as some examples on how to use newly introduced functionality.

Changes in MvcSiteMapProvider 2.2.0

  • Increased stability
  • HtmlHelpers upgraded to return MvcHtmlString
  • Templated HtmlHelpers have been introduced
  • New extensibility point: OnBeforeAddNode and OnAfterAddNode
  • Optimized sitemap XML for search engine indexing

Templated HtmlHelpers

The MvcSiteMapProvider provides different HtmlHelper extension methods which you can use to generate SiteMap-specific HTML code on your ASP.NET MVC views like a menu, a breadcrumb (sitemap path), a sitemap or just the current node’s title.

All helpers in MvcSiteMapProvider are make use of templates: whenever a node in a menu is to be rendered, a specific partial view is used to render this node. This is based on the idea of templated helpers. The default templates that are used can be found on the downloads page. Locate them under the Views/DisplayTemplates folder of your project to be able to customize them.

When creating your own templates for MvcSiteMapProvider's helpers, the following model objects are used and can be templated:

  • Html.MvcSiteMap().Menu() uses:
    MvcSiteMapProvider.Web.Html.Models.MenuHelperModel and MvcSiteMapProvider.Web.Html.Models.SiteMapNodeModel
  • Html.MvcSiteMap().SiteMap() uses:
    MvcSiteMapProvider.Web.Html.Models.SiteMapHelperModel and MvcSiteMapProvider.Web.Html.Models.SiteMapNodeModel
  • Html.MvcSiteMap().SiteMapPath() uses:
    MvcSiteMapProvider.Web.Html.Models.SiteMapPathHelperModel and MvcSiteMapProvider.Web.Html.Models.SiteMapNodeModel
  • Html.MvcSiteMap().SiteMapTitle()
    MvcSiteMapProvider.Web.Html.Models.Situses:eMapTitleHelperModel

The following template is an example for rendering a sitemap node represented by the MvcSiteMapProvider.Web.Html.Models.SiteMapNodeModel model.

1 <%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<MvcSiteMapProvider.Web.Html.Models.SiteMapNodeModel>" %> 2 <%@ Import Namespace="System.Web.Mvc.Html" %> 3 4 <% if (Model.IsCurrentNode && Model.SourceMetadata["HtmlHelper"].ToString() != "MvcSiteMapProvider.Web.Html.MenuHelper") { %> 5 <%=Model.Title %> 6 <% } else if (Model.IsClickable) { %> 7 <a href="<%=Model.Url %>"><%=Model.Title %></a> 8 <% } else { %> 9 <%=Model.Title %> 10 <% } %>

New extensibility point

In the previous release, a number of extensibility points have been introduced. I blogged about them before. A newly introduced extensibility point is the ISiteMapProviderEventHandler . A class implementing MvcSiteMapProvider.Extensibility.ISiteMapProviderEventHandler can be registered to handle specific events, such as when adding a SiteMapNode.

Here’s an example to log all the nodes that are being added to an MVC sitemap:

1 public class MySiteMapProviderEventHandler : ISiteMapProviderEventHandler 2 { 3 public bool OnAddingSiteMapNode(SiteMapProviderEventContext context) 4 { 5 // Should the node be added? Well yes! 6 return true; 7 } 8 9 public void OnAddedSiteMapNode(SiteMapProviderEventContext context) 10 { 11 Trace.Write("Node added: " + context.CurrentNode.Title); 12 } 13 }

Optimized sitemap XML for SEO

Generating a search-engine friendly list of all nodes in a sitemap was already possible. This functionality has been vastly improved with two new features:

  • Whenever a client sends an HTTP request header with Accept-encoding set to a value of gzip or deflate, the XmlSiteMapResult class (which is also used internally in the XmlSiteMapController) will automatically compress the sitemap using GZip compression.
  • Whenever a sitemap exceeds 50.000 nodes, the XmlSiteMapController will automatically split your sitemap into a sitemap index file (sitemap.xml) which references sub-sitemaps (sitemap-1.xml, sitemap-2.xml etc.) as described on http://www.sitemaps.org/protocol.php.

For example, if a website contains more than 50.000 nodes, the sitemap XML that is generated will look similar to the following:

1 <?xml version="1.0" encoding="utf-8" ?> 2 <sitemapindex xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"> 3 <sitemap> 4 <loc>http://localhost:1397/sitemap-1.xml</loc> 5 </sitemap> 6 <sitemap> 7 <loc>http://localhost:1397/sitemap-2.xml</loc> 8 </sitemap> 9 </sitemapindex>

This sitemap index links to sub-sitemap files where all nodes are included.

This is an imported post. It was imported from my old blog using an automated tool and may contain formatting errors and/or broken images.

Leave a Comment

avatar

3 responses

  1. Avatar for Paul
    Paul October 30th, 2010

    Very cool. Implementing this in my next project. Thanks for the hard work!

  2. Avatar for Fernando B
    Fernando B November 2nd, 2010

    Can you provide an example on how to use the new output templates? I'm not sure if I'm doing it right. I create a "DisplayTemplates" folder under the "Views" folder in my project. Then i added a "Test.ascx" partial view, in it I put:

    <%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<MvcSiteMapProvider.Web.Html.Models.MenuHelperModel>" %>
    <%@ Import Namespace="System.Web.Mvc.Html" %>

    <ul class="test">
    <% foreach (var node in Model.Nodes) { %>
    <li><%=Html.DisplayFor(m => node)%>
    <% if (node.Children.Any()) { %>
    <%=Html.DisplayFor(m => node.Children)%>
    <% } %>
    </li>
    <% } %>
    </ul>

    Then when i use the HtmlHelper like so: Html.MvcSiteMap().Menu("Test")
    I get an exception: System.ArgumentNullException: Value cannot be null.
    Parameter name: stream
    ...
    MvcSiteMapProvider.Web.Html.MenuHelper.Menu(MvcSiteMapHtmlHelper helper, String templateName, Boolean showStartingNode) in C:\Projects\Codeplex\TFS10\mvcsitemap\Main\MvcSiteMapProvider\MvcSiteMapProvider\Web\Html\MenuHelper.cs:156
    ...

    I've been using the previous version of the MvcSitemapProvider for a while but I really need the ability to customize the html that is being generated. Thanks for this awesome tool, great work!

  3. Avatar for Fernando B
    Fernando B November 2nd, 2010

    After reading the "Walkthrough: Using Templated Helpers to Display Data in ASP.NET MVC" (http://msdn.microsoft.com/e... article I quickly figured out what was wrong. Like I figured, it was such a simple mistake. The "DisplayTemplates" folder shoud go under the "Views\Shared\" folder in your project, not under "Views" like you specify in this blog and in the Codeplex documentation (http://mvcsitemap.codeplex..... If you could update the docs on the Codeplex site I'm sure you will save newbies like me some time :D

    Again, thanks for all the hard work!