Legacy ASP.NET Web Forms SiteMap
In .NET Framework 4.8, the System.Web.SiteMap hierarchy allows declarative navigation. A Web.sitemap XML file defines nodes, and controls like SiteMapDataSource bind to Menu or TreeView. The XmlSiteMapProvider reads the file automatically. This relies on System.Web, which is not ported to Core.
ASP.NET Core Navigation Structures
ASP.NET Core 8 does not include a sitemap provider. Navigation menus are typically built using: - View Components: Render shared UI logic like menus across pages. - Tag Helpers: Generate active link states based on the current route. - Razor Pages or MVC Views: Iterate over a list of menu items injected via dependency injection. Configuration for menu items should use the Options pattern (IOptions<MenuConfig>) rather than hardcoding.
Generating SEO Sitemaps in ASP.NET Core
For search engine optimization, developers create an endpoint returning an XML document. This endpoint queries the database for public content URLs and serializes them into the sitemap protocol format. The response content type must be application/xml. Services accessing databases should be registered as Scoped to align with DbContext lifetimes.
Code Example
using System.Collections.Generic;
using System.Linq;
using System.Xml.Linq;
using Microsoft.AspNetCore.Mvc;
[ApiController]
[Route("[controller]")]
public class SitemapController : ControllerBase
{
private readonly IContentService _contentService;
// Scoped lifetime recommended for service accessing DbContext
public SitemapController(IContentService contentService)
{
_contentService = contentService;
}
[HttpGet("xml")]
public async Task<IActionResult> GetSitemapXml()
{
var items = await _contentService.GetPublicUrlsAsync();
var xml = GenerateSitemapXml(items);
return Content(xml, "application/xml");
}
private string GenerateSitemapXml(IEnumerable<string> urls)
{
const string ns = "http://www.sitemaps.org/schemas/sitemap/0.9";
var doc = new XDocument(
new XDeclaration("1.0", "UTF-8", null),
new XElement(XName.Get("urlset", ns),
urls.Select(u => new XElement(XName.Get("url", ns),
new XElement(XName.Get("loc", ns), u)))
)
);
return doc.ToString();
}
}
Best Practices and Common Pitfalls
-
Avoid Legacy Dependencies: Do not attempt to port System.Web.SiteMap to Core; it is incompatible.
-
Caching: Cache the SEO sitemap XML output using response caching, as regeneration on every request is expensive.
-
Security: Ensure only public URLs are included; never expose admin or authenticated routes in a public sitemap.
-
Async Operations: Always use async methods when fetching data for the sitemap to avoid blocking threads.