Search code examples
c#xmlasp.net-coreasp.net-core-3.1xml-sitemap

Serving dynamic sitemap.xml content


How can I serve a dynamic sitemap.xml file from ASP.NET Core 3.1?

I tried something like:

...
public ActionResult SiteMap()
{
    // logic here
    return Content("<sitemap>...</sitemap>", "text/xml");
}
...

Solution

  • Yes, that's exactly the right approach. Of course, assuming you're using the standard sitemap protocol you'll need to:

    1. Establish an XML declaration (e.g., <?xml version="1.0" encoding="UTF-8"?>)
    2. Start with a <urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" /> element

    So, for example, if you want to assembly your XML using an XDocument, you could start with something like:

    private static readonly XNamespace _sitemapNamespace = "http://www.sitemaps.org/schemas/sitemap/0.9";
    private static readonly XNamespace _pagemapNamespace = "http://www.google.com/schemas/sitemap-pagemap/1.0";
    
    public ActionResult Sitemap() {
      var xml = new XDocument(
        new XDeclaration("1.0", "utf-8", String.Empty),
        new XElement(_sitemapNamespace + "urlset",
          //Your logic here
        )
      return Content(sitemap.ToString(), "text/xml");
      );
    }
    

    That said, with this code, you'll run into an issue with your XML declaration not being returned with your XML, since XDocument.ToString() only returns an XML snippet. To fix this, you need to wrap your XDocument in e.g. a StringWriter:

    var sitemapFile = new StringBuilder();
    using (var writer = new StringWriter(sitemapFile)) {
      sitemap.Save(writer);
    }
    return Content(sitemapFile.ToString(), "text/xml");
    

    Note: There are obviously other approaches for dynamically generating your XML. If you're using an XmlWriter or an XmlDocument, your code will look quite different. The point is to help fill out what a real-world implementation might look like, not to prescribe an exclusive approach.

    Are there specific problems you're running into with your attempt? If so, I may be able to provide more specific guidance. But, as is, the approach you are taking is correct.