• Home
  • Tutorials
  • Development Tools
  • Contact Us

Developing Software

Mastering Software Craftsmanship

How to Generate a Sitemap in ASP.NET MVC and ASP.NET Core

14th March 2016 by @developingsoft

A sitemap is good for SEO because it tells search engines what pages of your site it should index. But how do we create a sitemap in ASP.NET Core? In this post I will show you a very simple way to generate a sitemap that works in ASP.NET MVC and ASP.NET Core web projects.

Sample XML Sitemap

The following sample XML Sitemap is what we need to return when we visit http://www.example.com/sitemap

<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
    <url>
        <loc>http://www.example.com/</loc>
        <lastmod>2005-01-01</lastmod>
        <changefreq>monthly</changefreq>
        <priority>0.8</priority>
    </url>
</urlset> 

We can accomplish this in three easy steps.

Step 1: Create a SitemapUrl object

First we need to create a SitemapUrl object to hold information about each page URL.

public enum ChangeFrequency
{
    Always,
    Hourly,
    Daily,
    Weekly,
    Monthly,
    Yearly,
    Never
}

public class SitemapUrl
{
    public string Url { get; set; }
    public DateTime? Modified { get; set; }
    public ChangeFrequency? ChangeFrequency { get; set; }
    public double? Priority { get; set; }
}

Step 2: Create the SitemapBuilder class

The next step is to create a SitemapBuilder class that our MVC application can use to construct the sitemap.

public class SitemapBuilder
{
    private readonly XNamespace NS = "http://www.sitemaps.org/schemas/sitemap/0.9";

    private List<SitemapUrl> _urls;

    public SitemapBuilder()
    {
        _urls = new List<SitemapUrl>();
    }

    public void AddUrl(string url, DateTime? modified = null, ChangeFrequency? changeFrequency = null, double? priority = null)
    {
        _urls.Add(new SitemapUrl()
        {
            Url = url,
            Modified = modified,
            ChangeFrequency = changeFrequency,
            Priority = priority,
        });
    }

    public override string ToString()
    {
        var sitemap = new XDocument(
            new XDeclaration("1.0", "utf-8", "yes"),
            new XElement(NS + "urlset",
                from item in _urls
                select CreateItemElement(item)
                ));

        return sitemap.ToString();            
    }

    private XElement CreateItemElement(SitemapUrl url)
    {
        XElement itemElement = new XElement(NS + "url", new XElement(NS + "loc", url.Url.ToLower()));

        if (url.Modified.HasValue)
        {
            itemElement.Add(new XElement(NS + "lastmod", url.Modified.Value.ToString("yyyy-MM-ddTHH:mm:ss.f") + "+00:00"));
        }

        if (url.ChangeFrequency.HasValue)
        {
            itemElement.Add(new XElement(NS + "changefreq", url.ChangeFrequency.Value.ToString().ToLower()));
        }

        if (url.Priority.HasValue)
        {
            itemElement.Add(new XElement(NS + "priority", url.Priority.Value.ToString("N1")));
        }

        return itemElement;
    }
}

Note: The following reference needs added to your project.json file for the code above to work in ASP.NET Core.

"System.Xml.XmlDocument": "4.0.1-beta-23516"

Step 3: Generating the Sitemap in ASP.NET Core by creating a SitemapController

The following example shows how the SitemapBuilder can be used from an ASP.NET Core project.

public class SitemapController : Controller
{
    private readonly IBlogService _blogService;
    public SitemapController(IBlogService blogService)
    {
        _blogService = blogService;
    }

    [Route("sitemap")]
    public async Task<ActionResult> SitemapAsync()
    {
        string baseUrl = "https://developingsoftware.com/";

        // get a list of published articles
        var posts = await _blogService.PostService.GetPostsAsync();

        // get last modified date of the home page
        var siteMapBuilder = new SitemapBuilder();

        // add the home page to the sitemap
        siteMapBuilder.AddUrl(baseUrl, modified: DateTime.UtcNow, changeFrequency: ChangeFrequency.Weekly, priority: 1.0);

        // add the blog posts to the sitemap
        foreach(var post in posts)
        {
            siteMapBuilder.AddUrl(baseUrl + post.Slug, modified: post.Published, changeFrequency: null, priority: 0.9);
        }

        // generate the sitemap xml
        string xml = siteMapBuilder.ToString();
        return Content(xml, "text/xml");
    }
}

As you can see from the code above, the SitemapBuilder works similar to a StringBuilder in that each URL is added via the AddUrl method and then the XML Sitemap is generated using the final call to ToString.

This is a very simple way of generating a sitemap for a simple use case (it’s how the sitemap for this site is generated). There are many improvements that could be made like creating a SitemapAttribute and splitting the Sitemap into multiple pages but this sample is good enough for simple applications.

Update – It used to be how the sitemap for this site was generated before I migrated to WordPress.

Share this on:

Filed Under: Tutorials Tagged With: ASP.NET Core, ASP.NET MVC, C#

Search

Advertisement

Newsletter

Subscribe now to receive practical tips on how to become a better software developer.

Free - No Spam - 100% Email Privacy

Featured Posts

Abstract Factory Pattern: C# Example Using the Unity Game Engine

23 Software Design Patterns That Will Make You a More Effective Programmer

How to Deploy an ASP.NET Core Website to Ubuntu with Git

How to Run an ASP.NET Core Website in Production on Ubuntu Linux

How to Install the Edimax Wireless nano USB Adapter on Windows IoT Core for Raspberry Pi

How to Convert a Post Title into a Friendly URL (Slug) in C#

How to Convert Markdown to HTML in ASP.NET Core

How to Send an E-Mail with ASP.NET Core and Mailgun

How to Generate a Sitemap in ASP.NET MVC and ASP.NET Core

How to Create an MD5 Hash of a String in C# and Displaying a Gravatar Image

© 2014–2023 Developing SoftwareTerms • Privacy