Skip to content

Commit 6578799

Browse files
fix: improve in-memory sitemap endpoint quality and correctness
Follow-up addressing issues from dual AI review (GPT-5.5 + Opus 4.6). - Use [OutputCache(Duration=3600)] instead of [ResponseCache]; register AddOutputCache/UseOutputCache in Program.cs for real server-side caching - Remove [FromServices] workaround; expose protected RouteConfigurationService in BaseController to avoid CS9107 double-capture - Drop LastModificationDate on static controller routes (UtcNow as lastmod is an SEO anti-pattern) - Filter sitemap route from route discovery so /sitemap.xml does not list itself - Add [EnableRateLimiting] to SitemapXml action for consistency - Accept IEnumerable<SiteMapping> to avoid unnecessary .ToList() allocation - Fix startup log messages: generation -> validation
1 parent d0e1672 commit 6578799

4 files changed

Lines changed: 17 additions & 12 deletions

File tree

EssentialCSharp.Web/Controllers/BaseController.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ protected BaseController(IRouteConfigurationService routeConfigurationService, I
1616
_HttpContextAccessor = httpContextAccessor;
1717
}
1818

19+
protected IRouteConfigurationService RouteConfigurationService => _RouteConfigurationService;
20+
1921
public override void OnActionExecuting(ActionExecutingContext context)
2022
{
2123
// Automatically add static routes to all views

EssentialCSharp.Web/Controllers/HomeController.cs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
using EssentialCSharp.Web.Services;
66
using HtmlAgilityPack;
77
using Microsoft.AspNetCore.Mvc;
8+
using Microsoft.AspNetCore.OutputCaching;
89
using Microsoft.AspNetCore.RateLimiting;
910
using Microsoft.CodeAnalysis;
1011
using Microsoft.Extensions.Options;
@@ -90,10 +91,11 @@ public IActionResult Guidelines()
9091
}
9192

9293
[Route("/sitemap.xml")]
93-
[ResponseCache(Duration = 3600)]
94-
public IActionResult SitemapXml([FromServices] IRouteConfigurationService sitemapRouteConfig)
94+
[OutputCache(Duration = 3600)]
95+
[EnableRateLimiting("content")]
96+
public IActionResult SitemapXml()
9597
{
96-
SitemapXmlHelpers.GenerateSitemapXml(siteMappingService.SiteMappings.ToList(), sitemapRouteConfig, siteSettings.Value.BaseUrl, out var nodes);
98+
SitemapXmlHelpers.GenerateSitemapXml(siteMappingService.SiteMappings, RouteConfigurationService, siteSettings.Value.BaseUrl, out var nodes);
9799
return new SitemapProvider().CreateSitemap(new SitemapModel(nodes));
98100
}
99101

EssentialCSharp.Web/Helpers/SitemapXmlHelpers.cs

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ public static void EnsureSitemapHealthy(List<SiteMapping> siteMappings)
1818
}
1919
}
2020

21-
public static void GenerateSitemapXml(List<SiteMapping> siteMappings, IRouteConfigurationService routeConfigurationService, string baseUrl, out List<SitemapNode> nodes)
21+
public static void GenerateSitemapXml(IEnumerable<SiteMapping> siteMappings, IRouteConfigurationService routeConfigurationService, string baseUrl, out List<SitemapNode> nodes)
2222
{
2323
DateTime newDateTime = DateTime.UtcNow;
2424

@@ -38,18 +38,17 @@ public static void GenerateSitemapXml(List<SiteMapping> siteMappings, IRouteConf
3838
// Add routes dynamically discovered from controllers
3939
var allRoutes = routeConfigurationService.GetStaticRoutes();
4040
var controllerRoutes = allRoutes
41-
.Where(route => !route.Contains("error", StringComparison.OrdinalIgnoreCase)) // Skip Error actions for sitemap
42-
.Where(route => !route.Contains("index", StringComparison.OrdinalIgnoreCase)) // Skip Index actions for sitemap
43-
.Where(route => !route.Contains("identity", StringComparison.OrdinalIgnoreCase)) // Skip Identity actions for sitemap
44-
// All routes should have leading slash
45-
.Select(route => $"/{route}") // Add leading slash for sitemap URLs
41+
.Where(route => !route.Contains("error", StringComparison.OrdinalIgnoreCase))
42+
.Where(route => !route.Contains("index", StringComparison.OrdinalIgnoreCase))
43+
.Where(route => !route.Contains("identity", StringComparison.OrdinalIgnoreCase))
44+
.Where(route => !route.Contains("sitemap", StringComparison.OrdinalIgnoreCase))
45+
.Select(route => $"/{route}")
4646
.ToList();
4747

4848
foreach (var route in controllerRoutes)
4949
{
5050
nodes.Add(new($"{baseUrl}{route}")
5151
{
52-
LastModificationDate = newDateTime,
5352
ChangeFrequency = GetChangeFrequencyForRoute(route),
5453
Priority = GetPriorityForRoute(route)
5554
});

EssentialCSharp.Web/Program.cs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -243,6 +243,7 @@ private static void Main(string[] args)
243243

244244
// Add services to the container.
245245
builder.Services.AddRazorPages();
246+
builder.Services.AddOutputCache();
246247
builder.Services.AddCaptchaService(builder.Configuration.GetSection(CaptchaOptions.CaptchaSender));
247248
builder.Services.AddSingleton<ISiteMappingService, SiteMappingService>();
248249
builder.Services.AddSingleton<IRouteConfigurationService, RouteConfigurationService>();
@@ -505,6 +506,7 @@ await McpJsonRpcResponseWriter.WriteErrorAsync(
505506
app.UseStaticFiles();
506507

507508
app.UseRouting();
509+
app.UseOutputCache();
508510

509511
app.UseWhen(
510512
context => context.Request.Path.StartsWithSegments("/mcp"),
@@ -596,10 +598,10 @@ private static bool IsMcpTransportRequest(HttpRequest request) =>
596598
[LoggerMessage(Level = LogLevel.Error, Message = "Unhandled exception on {Path}")]
597599
private static partial void LogUnhandledException(ILogger<Program> logger, Exception? exception, PathString path);
598600

599-
[LoggerMessage(Level = LogLevel.Information, Message = "Sitemap.xml generation completed successfully during application startup")]
601+
[LoggerMessage(Level = LogLevel.Information, Message = "Sitemap validation completed successfully during application startup")]
600602
private static partial void LogSitemapGenerationSucceeded(ILogger<Program> logger);
601603

602-
[LoggerMessage(Level = LogLevel.Error, Message = "Failed to generate sitemap.xml during application startup")]
604+
[LoggerMessage(Level = LogLevel.Error, Message = "Failed to validate sitemap during application startup")]
603605
private static partial void LogSitemapGenerationFailed(ILogger<Program> logger, Exception exception);
604606

605607
[LoggerMessage(Level = LogLevel.Warning, Message = "Ignoring invalid TryDotNet origin in CSP: {Origin}")]

0 commit comments

Comments
 (0)