/// <inheritdoc /> public async Task RouteAsync(RouteContext context) { foreach (var tree in _trees) { var tokenizer = new PathTokenizer(context.HttpContext.Request.Path); var root = tree.Root; var treeEnumerator = new TreeEnumerator(root, tokenizer); // Create a snapshot before processing the route. We'll restore this snapshot before running each // to restore the state. This is likely an "empty" snapshot, which doesn't allocate. var snapshot = context.RouteData.PushState(router: null, values: null, dataTokens: null); while (treeEnumerator.MoveNext()) { var node = treeEnumerator.Current; foreach (var item in node.Matches) { var entry = item.Entry; var matcher = item.TemplateMatcher; if (!matcher.TryMatch(context.HttpContext.Request.Path, context.RouteData.Values)) { continue; } try { if (!RouteConstraintMatcher.Match( entry.Constraints, context.RouteData.Values, context.HttpContext, this, RouteDirection.IncomingRequest, _constraintLogger)) { continue; } _logger.MatchedRoute(entry.RouteName, entry.RouteTemplate.TemplateText); context.RouteData.Routers.Add(entry.Handler); await entry.Handler.RouteAsync(context); if (context.Handler != null) { return; } } finally { if (context.Handler == null) { // Restore the original values to prevent polluting the route data. snapshot.Restore(); } } } } } }
/// <inheritdoc /> public async Task RouteAsync(RouteContext context) { foreach (var tree in _trees) { var tokenizer = new PathTokenizer(context.HttpContext.Request.Path); var enumerator = tokenizer.GetEnumerator(); var root = tree.Root; var treeEnumerator = new TreeEnumerator(root, tokenizer); while (treeEnumerator.MoveNext()) { var node = treeEnumerator.Current; foreach (var item in node.Matches) { var values = item.TemplateMatcher.Match(context.HttpContext.Request.Path); if (values == null) { continue; } var match = new TemplateMatch(item, values); var snapshot = context.RouteData.PushState(match.Entry.Target, match.Values, dataTokens: null); try { if (!RouteConstraintMatcher.Match( match.Entry.Constraints, context.RouteData.Values, context.HttpContext, this, RouteDirection.IncomingRequest, _constraintLogger)) { continue; } _logger.MatchedRoute(match.Entry.RouteName, match.Entry.RouteTemplate.TemplateText); await match.Entry.Target.RouteAsync(context); if (context.Handler != null) { return; } } finally { if (context.Handler == null) { // Restore the original values to prevent polluting the route data. snapshot.Restore(); } } } } } }