diff --git a/src/Microsoft.AspNetCore.Mvc.Core/Internal/MvcAttributeRouteHandler.cs b/src/Microsoft.AspNetCore.Mvc.Core/Internal/MvcAttributeRouteHandler.cs index 4324adb3a4..9da2c28199 100644 --- a/src/Microsoft.AspNetCore.Mvc.Core/Internal/MvcAttributeRouteHandler.cs +++ b/src/Microsoft.AspNetCore.Mvc.Core/Internal/MvcAttributeRouteHandler.cs @@ -78,7 +78,7 @@ namespace Microsoft.AspNetCore.Mvc.Internal var actionDescriptor = _actionSelector.SelectBestCandidate(context, Actions); if (actionDescriptor == null) { - _logger.NoActionsMatched(); + _logger.NoActionsMatched(context.RouteData.Values); return TaskCache.CompletedTask; } diff --git a/src/Microsoft.AspNetCore.Mvc.Core/Internal/MvcCoreLoggerExtensions.cs b/src/Microsoft.AspNetCore.Mvc.Core/Internal/MvcCoreLoggerExtensions.cs index 5131e0a064..8c725e7687 100644 --- a/src/Microsoft.AspNetCore.Mvc.Core/Internal/MvcCoreLoggerExtensions.cs +++ b/src/Microsoft.AspNetCore.Mvc.Core/Internal/MvcCoreLoggerExtensions.cs @@ -67,6 +67,8 @@ namespace Microsoft.AspNetCore.Mvc.Internal private static readonly Action _redirectToRouteResultExecuting; + private static readonly Action _noActionsMatched; + static MvcCoreLoggerExtensions() { _actionExecuting = LoggerMessage.Define( @@ -223,6 +225,11 @@ namespace Microsoft.AspNetCore.Mvc.Internal LogLevel.Information, 1, "Executing RedirectToRouteResult, redirecting to {Destination} from route {RouteName}."); + + _noActionsMatched = LoggerMessage.Define( + LogLevel.Debug, + 3, + "No actions matched the current request. Route values: {RouteValues}"); } public static IDisposable ActionScope(this ILogger logger, ActionDescriptor action) @@ -250,9 +257,19 @@ namespace Microsoft.AspNetCore.Mvc.Internal } } - public static void NoActionsMatched(this ILogger logger) + public static void NoActionsMatched(this ILogger logger, IDictionary routeValueDictionary) { - logger.LogDebug(3, "No actions matched the current request"); + if (logger.IsEnabled(LogLevel.Debug)) + { + string[] routeValues = null; + if (routeValueDictionary != null) + { + routeValues = routeValueDictionary + .Select(pair => pair.Key + "=" + Convert.ToString(pair.Value)) + .ToArray(); + } + _noActionsMatched(logger, routeValues, null); + } } public static void ChallengeResultExecuting(this ILogger logger, IList schemes) diff --git a/src/Microsoft.AspNetCore.Mvc.Core/Internal/MvcRouteHandler.cs b/src/Microsoft.AspNetCore.Mvc.Core/Internal/MvcRouteHandler.cs index 9f5e84a505..d377c59f76 100644 --- a/src/Microsoft.AspNetCore.Mvc.Core/Internal/MvcRouteHandler.cs +++ b/src/Microsoft.AspNetCore.Mvc.Core/Internal/MvcRouteHandler.cs @@ -66,14 +66,14 @@ namespace Microsoft.AspNetCore.Mvc.Internal var candidates = _actionSelector.SelectCandidates(context); if (candidates == null || candidates.Count == 0) { - _logger.NoActionsMatched(); + _logger.NoActionsMatched(context.RouteData.Values); return TaskCache.CompletedTask; } var actionDescriptor = _actionSelector.SelectBestCandidate(context, candidates); if (actionDescriptor == null) { - _logger.NoActionsMatched(); + _logger.NoActionsMatched(context.RouteData.Values); return TaskCache.CompletedTask; } diff --git a/test/Microsoft.AspNetCore.Mvc.Core.Test/Infrastructure/MvcRouteHandlerTests.cs b/test/Microsoft.AspNetCore.Mvc.Core.Test/Infrastructure/MvcRouteHandlerTests.cs index 01cff77051..aa839616c0 100644 --- a/test/Microsoft.AspNetCore.Mvc.Core.Test/Infrastructure/MvcRouteHandlerTests.cs +++ b/test/Microsoft.AspNetCore.Mvc.Core.Test/Infrastructure/MvcRouteHandlerTests.cs @@ -30,12 +30,14 @@ namespace Microsoft.AspNetCore.Mvc.Infrastructure .Returns(new ActionDescriptor[0]); var context = CreateRouteContext(); + context.RouteData.Values.Add("controller", "Home"); + context.RouteData.Values.Add("action", "Index"); var handler = CreateMvcRouteHandler( actionSelector: mockActionSelector.Object, loggerFactory: loggerFactory); - var expectedMessage = "No actions matched the current request"; + var expectedMessage = "No actions matched the current request. Route values: controller=Home, action=Index"; // Act await handler.RouteAsync(context);