Skip to content

Instantly share code, notes, and snippets.

@jordanwallwork
Created August 18, 2016 11:37
Show Gist options
  • Save jordanwallwork/b8829994194600fc01332ec84c43a659 to your computer and use it in GitHub Desktop.
Save jordanwallwork/b8829994194600fc01332ec84c43a659 to your computer and use it in GitHub Desktop.
dotnet core mvc sitemap generator
// Modified code from http://dotnetthoughts.net/generate-dynamic-xml-sitemaps-in-aspnet5/
public static class SitemapGenerator
{
private static string _sitemapContent = null;
public static string Generate(string rootUrl, IUrlHelper urlHelper)
{
if (_sitemapContent == null) // I only wanted to generate this once and then stash the result. Caching the action that calls this would probably be better
{
string sitemapContent = "<urlset xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\">";
var controllers = Assembly.GetExecutingAssembly().GetTypes().Where(type => typeof(Controller).IsAssignableFrom(type) || type.Name.EndsWith("controller")).ToList();
foreach (var controller in controllers)
{
var methods = controller.GetMethods(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly)
.Where(method => typeof(IActionResult).IsAssignableFrom(method.ReturnType))
.Where(method => controller.GetCustomAttributes(typeof(IncludeInSitemapAttribute), true).Any() || method.GetCustomAttributes(typeof(IncludeInSitemapAttribute), true).Any())
.Where(method => !method.GetCustomAttributes(typeof(ExcludeFromSitemapAttribute), true).Any());
foreach (var method in methods)
{
sitemapContent += "<url>";
var action = method.Name.ToLower();
var ctrl = controller.Name.ToLower().Replace("controller", "");
var route = rootUrl + urlHelper.Action(action, ctrl).TrimEnd('/'); // Generate correct route with mvc router
sitemapContent += $"<loc>{route}</loc>";
//sitemapContent += string.Format("<lastmod>{0}</lastmod>", DateTime.UtcNow.ToString("yyyy-MM-dd")); // I didn't want this but uncomment if required
sitemapContent += "</url>";
}
}
sitemapContent += "</urlset>";
_sitemapContent = sitemapContent;
}
return _sitemapContent;
}
}
public class IncludeInSitemapAttribute : Attribute { }
public class ExcludeFromSitemapAttribute : Attribute { }
public class HomeController : Controller {
private readonly string _rootUrl;
public HomeController(string rootUrl) {
_rootUrl = rootUrl;
}
[Route("sitemap.xml")]
[ExcludeFromSitemap]
public ContentResult Sitemap(string id) => Content(SitemapGenerator.Generate(_rootUrl, Url), "application/xml");
[IncludeInSitemap] // Include individual action
public IActionResult Index() => View();
[ExcludeFromSitemap] // Exclude individual action
public IActionResult Secret() => View();
}
[ExcludeFromSitemap] // all actions will be excluded
public PrivateController : Controller {
public IActionResult Private1() => View();
public IActionResult Private2() => View();
public IActionResult Private3() => View();
}
[IncludeInSitemap] // all actions will be included
public PublicController : Controller {
public IActionResult Public1() => View();
public IActionResult Public2() => View();
public IActionResult Public3() => View();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment