using NoticeBoard.Data; using Microsoft.EntityFrameworkCore; namespace NoticeBoard.Routing; public class DeviceSlugConstraint : IRouteConstraint { // Reserved paths that should NOT be treated as device slugs private static readonly HashSet ReservedPaths = new(StringComparer.OrdinalIgnoreCase) { "admin", "api", "d", "error", "css", "js", "lib", "uploads", "favicon.ico" }; public bool Match(HttpContext? httpContext, IRouter? route, string routeKey, RouteValueDictionary values, RouteDirection routeDirection) { if (values.TryGetValue(routeKey, out var value) && value is string slug) { // Block reserved paths if (ReservedPaths.Contains(slug)) return false; // Only match lowercase alphanumeric + hyphens return slug.All(c => char.IsLetterOrDigit(c) || c == '-'); } return false; } }