namespace FileShare_Services.Core { /// /// Matches unified endpoint patterns and extracts simple route values. /// internal static class ServiceEndpointPatternMatcher { /// /// Match literal segments and single-segment route parameters such as {id} or {id:int}. /// public static bool TryMatch( string pattern, string path, out Dictionary routeValues) { routeValues = new Dictionary(StringComparer.OrdinalIgnoreCase); var patternSegments = SplitSegments(pattern); var pathSegments = SplitSegments(path); if (patternSegments.Length != pathSegments.Length) { return false; } for (var index = 0; index < patternSegments.Length; index++) { var patternSegment = patternSegments[index]; var pathSegment = pathSegments[index]; if (TryGetParameterName(patternSegment, out var parameterName)) { if (!MatchesConstraint(patternSegment, pathSegment)) { return false; } routeValues[parameterName] = Uri.UnescapeDataString(pathSegment); continue; } if (!string.Equals(patternSegment, pathSegment, StringComparison.OrdinalIgnoreCase)) { return false; } } return true; } /// /// 将路径按 / 拆分为非空片段数组。 /// /// 路径字符串。 /// 过滤空条目后的片段数组。 private static string[] SplitSegments(string value) { return value.Split('/', StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries); } /// /// 尝试从 {name}{name:constraint} 格式的片段中提取参数名称。 /// /// 模式片段。 /// 提取出的参数名称。 /// 该片段是路由参数时返回 true,否则 false。 private static bool TryGetParameterName(string segment, out string parameterName) { parameterName = string.Empty; if (segment.Length < 3 || segment[0] != '{' || segment[^1] != '}') { return false; } var token = segment[1..^1]; var constraintIndex = token.IndexOf(':'); parameterName = constraintIndex >= 0 ? token[..constraintIndex] : token; return !string.IsNullOrWhiteSpace(parameterName); } /// /// 检查路由值是否满足片段中的类型约束(目前仅支持 :int)。 /// /// 包含约束的模式片段。 /// 实际路径值。 /// 满足约束时返回 true。 private static bool MatchesConstraint(string segment, string value) { return !segment.EndsWith(":int}", StringComparison.OrdinalIgnoreCase) || int.TryParse(value, out _); } } }