diff --git a/samples/RoutingSample.Web/Program.cs b/samples/RoutingSample.Web/Program.cs
index 5867596559..1fa90c645c 100644
--- a/samples/RoutingSample.Web/Program.cs
+++ b/samples/RoutingSample.Web/Program.cs
@@ -4,6 +4,7 @@
using System;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
+using Microsoft.Extensions.Logging;
namespace RoutingSample.Web
{
@@ -59,7 +60,8 @@ namespace RoutingSample.Web
return new WebHostBuilder()
.UseKestrel()
.UseIISIntegration()
- .UseStartup(startupType);
+ .UseStartup(startupType)
+ .ConfigureLogging(l => l.AddConsole().SetMinimumLevel(LogLevel.Debug));
}
}
}
diff --git a/samples/RoutingSample.Web/RoutingSample.Web.csproj b/samples/RoutingSample.Web/RoutingSample.Web.csproj
index 52b1699c7b..d8cc8e8283 100644
--- a/samples/RoutingSample.Web/RoutingSample.Web.csproj
+++ b/samples/RoutingSample.Web/RoutingSample.Web.csproj
@@ -10,6 +10,7 @@
+
diff --git a/src/Microsoft.AspNetCore.Routing/DefaultLinkGenerator.cs b/src/Microsoft.AspNetCore.Routing/DefaultLinkGenerator.cs
index df52926a02..f050eecb97 100644
--- a/src/Microsoft.AspNetCore.Routing/DefaultLinkGenerator.cs
+++ b/src/Microsoft.AspNetCore.Routing/DefaultLinkGenerator.cs
@@ -4,6 +4,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
+using System.Text;
using System.Text.Encodings.Web;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Http.Extensions;
@@ -19,7 +20,6 @@ namespace Microsoft.AspNetCore.Routing
{
internal sealed class DefaultLinkGenerator : LinkGenerator
{
- private static readonly char[] UrlQueryDelimiters = new char[] { '?', '#' };
private readonly ParameterPolicyFactory _parameterPolicyFactory;
private readonly ObjectPool _uriBuildingContextPool;
private readonly ILogger _logger;
@@ -172,7 +172,18 @@ namespace Microsoft.AspNetCore.Routing
private List GetEndpoints(TAddress address)
{
var addressingScheme = _serviceProvider.GetRequiredService>();
- return addressingScheme.FindEndpoints(address).OfType().ToList();
+ var endpoints = addressingScheme.FindEndpoints(address).OfType().ToList();
+
+ if (endpoints.Count == 0)
+ {
+ Log.EndpointsNotFound(_logger, address);
+ }
+ else
+ {
+ Log.EndpointsFound(_logger, address, endpoints);
+ }
+
+ return endpoints;
}
// Also called from DefaultLinkGenerationTemplate
@@ -195,15 +206,17 @@ namespace Microsoft.AspNetCore.Routing
options,
out var result))
{
-
- return UriHelper.BuildRelative(
+ var uri = UriHelper.BuildRelative(
pathBase,
result.path,
result.query,
fragment);
+ Log.LinkGenerationSucceeded(_logger, endpoints, uri);
+ return uri;
}
}
+ Log.LinkGenerationFailed(_logger, endpoints);
return null;
}
@@ -229,16 +242,19 @@ namespace Microsoft.AspNetCore.Routing
options,
out var result))
{
- return UriHelper.BuildAbsolute(
+ var uri = UriHelper.BuildAbsolute(
scheme,
host,
pathBase,
result.path,
result.query,
fragment);
+ Log.LinkGenerationSucceeded(_logger, endpoints, uri);
+ return uri;
}
}
+ Log.LinkGenerationFailed(_logger, endpoints);
return null;
}
@@ -266,20 +282,25 @@ namespace Microsoft.AspNetCore.Routing
{
// We're missing one of the required values for this route.
result = default;
+ Log.TemplateFailedRequiredValues(_logger, endpoint, ambientValues, explicitValues);
return false;
}
if (!MatchesConstraints(httpContext, endpoint, templateValuesResult.CombinedValues))
{
result = default;
+
+ // MatchesConstraints does its own logging, so we're not logging here.
return false;
}
if (!templateBinder.TryBindValues(templateValuesResult.AcceptedValues, options, _globalLinkOptions, out result))
{
+ Log.TemplateFailedExpansion(_logger, endpoint, templateValuesResult.AcceptedValues);
return false;
}
+ Log.TemplateSucceeded(_logger, endpoint, result.path, result.query);
return true;
}
@@ -304,6 +325,7 @@ namespace Microsoft.AspNetCore.Routing
if (parameterPolicy is IRouteConstraint routeConstraint
&& !routeConstraint.Match(httpContext, NullRouter.Instance, kvp.Key, routeValues, RouteDirection.UrlGeneration))
{
+ Log.TemplateFailedConstraint(_logger, endpoint, kvp.Key, routeConstraint, routeValues);
return false;
}
}
@@ -317,5 +339,163 @@ namespace Microsoft.AspNetCore.Routing
{
return httpContext?.Features.Get()?.RouteValues;
}
+
+ private static class Log
+ {
+ public static class EventIds
+ {
+ public static readonly EventId EndpointsFound = new EventId(100, "EndpointsFound");
+ public static readonly EventId EndpointsNotFound = new EventId(101, "EndpointsNotFound");
+
+ public static readonly EventId TemplateSucceeded = new EventId(102, "TemplateSucceeded");
+ public static readonly EventId TemplateFailedRequiredValues = new EventId(103, "TemplateFailedRequiredValues");
+ public static readonly EventId TemplateFailedConstraint = new EventId(103, "TemplateFailedConstraint");
+ public static readonly EventId TemplateFailedExpansion = new EventId(104, "TemplateFailedExpansion");
+
+ public static readonly EventId LinkGenerationSucceeded = new EventId(105, "LinkGenerationSucceeded");
+ public static readonly EventId LinkGenerationFailed = new EventId(106, "LinkGenerationFailed");
+ }
+
+ private static readonly Action, object, Exception> _endpointsFound = LoggerMessage.Define, object>(
+ LogLevel.Debug,
+ EventIds.EndpointsFound,
+ "Found the endpoints {Endpoints} for address {Address}");
+
+ private static readonly Action _endpointsNotFound = LoggerMessage.Define