Search code examples
c#asp.net-mvcmvcsitemapproviderasp.net-mvc-sitemap

MVCSitemapProvider Issue with custom Route


I having difficulty to use the MVCSitemapProvider to generate a sitemap my case is this:

I have this :

 routes.MapRoute("Blog", "Blog/{id}/{seoName}", new { controller = "Blog", action = "ViewBlog", seoName = "" }, new { id = @"^\d+$" });

and I am using this as a atribute to my controller

            [MvcSiteMapNode(Title = "Blog", Key = "ViewBlog", ParentKey = "Blog",Route="Blog")]

the issue is the sitemap.xml contains this :

<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
<url>
<loc>http://localhost:7872/</loc>
</url>
<url>
<loc>http://localhost:7872/#</loc>
</url>
<url>
<loc>http://localhost:7872/Blog</loc>
</url>
<url>
<loc>http://localhost:7872/Home/About</loc>
</url>
</urlset>

My route is mapping to this URL : <loc>http://localhost:7872/#</loc> when I use the route=Blog

It was supposed to be something like this : localhost:7872/blog/idhere/friendurlName

the URL works fine, but I am trying to improve SEO and Sitemap is pretty much necessary I am not sure how to set this up. any ideas?


Solution

  • You should use a a dynamic node provider to make each blog post into a separate node. You also need to register the "id" and "seoName" route parameters with MvcSiteMapProvider or it will not be able to match the route or build the correct URL.

    [MvcSiteMapNode(DynamicNodeProvider = "MyNamespace.BlogDynamicNodeProvider, MyAssembly", Route = "Blog")]
    public ActionResult ViewBlog(int id, string seoName)
    {
        // Retrieve your blog post here...
    
        return View();
    }
    

    And in a code file in your project...

    public class BlogDynamicNodeProvider : DynamicNodeProviderBase
    {
        public override IEnumerable<DynamicNode> GetDynamicNodeCollection(ISiteMapNode node)
        {
            // BlogEntities would be your entity framework context class
            // or repository.
            using (var entities = new BlogEntities())
            {
                // Create a node for each blog post
                foreach (var blogPost in entities.BlogPosts)
                {
                    DynamicNode dynamicNode = new DynamicNode();
                    dynamicNode.Title = blogPost.Title;
                    dynamicNode.ParentKey = "Blog";
                    dynamicNode.Key = "BlogPost_" + blogPost.Id;
                    dynamicNode.RouteValues.Add("id", blogPost.Id);
                    dynamicNode.RouteValues.Add("seoName", blogPost.SeoName);
    
                    yield return dynamicNode;
                }
            }
        }
    }