diff --git a/src/Shared/LayoutRenderers/AspNetMvcActionRenderer.cs b/src/Shared/LayoutRenderers/AspNetMvcActionRenderer.cs index a5243c7f..a4805700 100644 --- a/src/Shared/LayoutRenderers/AspNetMvcActionRenderer.cs +++ b/src/Shared/LayoutRenderers/AspNetMvcActionRenderer.cs @@ -29,11 +29,12 @@ protected override void DoAppend(StringBuilder builder, LogEventInfo logEvent) var context = HttpContextAccessor.HttpContext; #if !ASP_NET_CORE - var controller = RouteTable.Routes?.GetRouteData(context)?.Values[key]?.ToString(); + object actionValue = null; + RouteTable.Routes?.GetRouteData(context)?.Values?.TryGetValue(key, out actionValue); #else - var controller = context?.GetRouteData()?.Values?[key]?.ToString(); + var actionValue = context?.GetRouteValue(key); #endif - builder.Append(controller); + builder.Append(actionValue?.ToString()); } } } \ No newline at end of file diff --git a/src/Shared/LayoutRenderers/AspNetMvcControllerRenderer.cs b/src/Shared/LayoutRenderers/AspNetMvcControllerRenderer.cs index eeee8e63..bdc4de10 100644 --- a/src/Shared/LayoutRenderers/AspNetMvcControllerRenderer.cs +++ b/src/Shared/LayoutRenderers/AspNetMvcControllerRenderer.cs @@ -28,12 +28,14 @@ protected override void DoAppend(StringBuilder builder, LogEventInfo logEvent) var context = HttpContextAccessor.HttpContext; + #if !ASP_NET_CORE - var controller = RouteTable.Routes?.GetRouteData(context)?.Values[key]?.ToString(); + object controllerValue = null; + RouteTable.Routes?.GetRouteData(context)?.Values?.TryGetValue(key, out controllerValue); #else - var controller = context?.GetRouteData()?.Values?[key]?.ToString(); + var controllerValue = context?.GetRouteValue(key); #endif - builder.Append(controller); + builder.Append(controllerValue?.ToString()); } } } \ No newline at end of file diff --git a/src/Shared/LayoutRenderers/AspNetRequestRouteParametersRenderer.cs b/src/Shared/LayoutRenderers/AspNetRequestRouteParametersRenderer.cs index 3a18b5ae..c54b8d39 100644 --- a/src/Shared/LayoutRenderers/AspNetRequestRouteParametersRenderer.cs +++ b/src/Shared/LayoutRenderers/AspNetRequestRouteParametersRenderer.cs @@ -1,12 +1,11 @@ using System.Text; -using NLog.LayoutRenderers; using System.Collections.Generic; -using System.Linq; #if !ASP_NET_CORE using System.Web.Routing; #else using Microsoft.AspNetCore.Routing; #endif +using NLog.LayoutRenderers; namespace NLog.Web.LayoutRenderers { @@ -28,7 +27,13 @@ public class AspNetRequestRouteParametersRenderer : AspNetLayoutMultiValueRender /// List Route Parameter' Key to be rendered from Request. /// If empty, then render all parameters /// - public List RouteParameterKeys { get; set; } + public List RouteParameterKeys { get => Items; set => Items = value; } + + /// + /// List Route Parameter' Key to be rendered from Request. + /// If empty, then render all parameters + /// + public List Items { get; set; } /// protected override void DoAppend(StringBuilder builder, LogEventInfo logEvent) @@ -39,41 +44,63 @@ protected override void DoAppend(StringBuilder builder, LogEventInfo logEvent) return; } + var routeParameterKeys = Items; + + if (routeParameterKeys?.Count == 1 && !string.IsNullOrEmpty(routeParameterKeys[0])) + { #if !ASP_NET_CORE - RouteValueDictionary routeParameters = RouteTable.Routes?.GetRouteData(context)?.Values; + object routeValue = null; + RouteTable.Routes?.GetRouteData(context)?.Values?.TryGetValue(routeParameterKeys[0], out routeValue); #else - RouteValueDictionary routeParameters = context.GetRouteData()?.Values; + var routeValue = context?.GetRouteValue(routeParameterKeys[0]); #endif - if (routeParameters == null || routeParameters.Count == 0) - { - return; - } + var routeStringValue = routeValue?.ToString(); + if (!string.IsNullOrEmpty(routeStringValue)) + { - var routeParameterKeys = RouteParameterKeys; - bool printAllRouteParameter = routeParameterKeys == null || routeParameterKeys.Count == 0; - if (printAllRouteParameter) + var pair = new[] { new KeyValuePair(routeParameterKeys[0], routeStringValue) }; + SerializePairs(pair, builder, logEvent); + } + } + else { - routeParameterKeys = routeParameters.Keys.ToList(); +#if !ASP_NET_CORE + RouteValueDictionary routeParameters = RouteTable.Routes?.GetRouteData(context)?.Values; +#else + RouteValueDictionary routeParameters = context.GetRouteData()?.Values; +#endif + if (routeParameters?.Count > 0) + { + var pairs = GetPairs(routeParameters, routeParameterKeys); + SerializePairs(pairs, builder, logEvent); + } } - - IEnumerable> pairs = GetPairs(routeParameters, routeParameterKeys); - SerializePairs(pairs, builder, logEvent); } private static IEnumerable> GetPairs(RouteValueDictionary routeParameters, List routeParameterKeys) { - foreach (string key in routeParameterKeys) + if (routeParameterKeys?.Count > 0) { - // This platform specific code is to prevent an unncessary .ToString call otherwise. - if (!routeParameters.TryGetValue(key, out object objValue)) + foreach (var routeKey in routeParameterKeys) { - continue; + if (routeParameters.TryGetValue(routeKey, out var routeValue)) + { + string value = routeValue?.ToString(); + if (!string.IsNullOrEmpty(value)) + yield return new KeyValuePair(routeKey, value); + } } - - string value = objValue?.ToString(); - if (!string.IsNullOrEmpty(value)) + } + else + { + // Output all route-values + foreach (var routeItem in routeParameters) { - yield return new KeyValuePair(key, value); + string routeValue = routeItem.Value?.ToString(); + if (!string.IsNullOrEmpty(routeValue)) + { + yield return new KeyValuePair(routeItem.Key, routeValue); + } } } } diff --git a/tests/NLog.Web.AspNetCore.Tests/LayoutRenderers/AspNetRequestTlsHandshakeLayoutRendererTests.cs b/tests/NLog.Web.AspNetCore.Tests/LayoutRenderers/AspNetRequestTlsHandshakeLayoutRendererTests.cs index e7859193..5c98258a 100644 --- a/tests/NLog.Web.AspNetCore.Tests/LayoutRenderers/AspNetRequestTlsHandshakeLayoutRendererTests.cs +++ b/tests/NLog.Web.AspNetCore.Tests/LayoutRenderers/AspNetRequestTlsHandshakeLayoutRendererTests.cs @@ -125,19 +125,6 @@ public void ProtocolTest() // Assert Assert.Equal(SslProtocols.Tls13.ToString(), result); } - - - protected override void NullRendersEmptyString() - { - // Arrange - var (renderer, _) = CreateWithHttpContext(); - - // Act - string result = renderer.Render(LogEventInfo.CreateNullEvent()); - - // Assert - Assert.Equal("None", result); - } } } #endif \ No newline at end of file diff --git a/tests/NLog.Web.AspNetCore.Tests/LayoutRenderers/AspNetRequestTrackingConsentLayoutRendererTests.cs b/tests/NLog.Web.AspNetCore.Tests/LayoutRenderers/AspNetRequestTrackingConsentLayoutRendererTests.cs index 183520f8..7f028da7 100644 --- a/tests/NLog.Web.AspNetCore.Tests/LayoutRenderers/AspNetRequestTrackingConsentLayoutRendererTests.cs +++ b/tests/NLog.Web.AspNetCore.Tests/LayoutRenderers/AspNetRequestTrackingConsentLayoutRendererTests.cs @@ -108,7 +108,7 @@ protected override void NullRendersEmptyString() string result = renderer.Render(LogEventInfo.CreateNullEvent()); // Assert - Assert.Equal("0", result); + Assert.Equal("1", result); } } } diff --git a/tests/Shared/LayoutRenderers/AspNetMvcActionRendererTests.cs b/tests/Shared/LayoutRenderers/AspNetMvcActionRendererTests.cs index 93979ba1..914317b9 100644 --- a/tests/Shared/LayoutRenderers/AspNetMvcActionRendererTests.cs +++ b/tests/Shared/LayoutRenderers/AspNetMvcActionRendererTests.cs @@ -6,32 +6,65 @@ using System.Collections.Specialized; using System.Web.SessionState; #else -using Microsoft.Extensions.Primitives; -using HttpContextBase = Microsoft.AspNetCore.Http.HttpContext; -using Microsoft.AspNetCore.Routing; +using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http.Features; +using Microsoft.AspNetCore.Routing; #endif using NLog.Web.LayoutRenderers; using NSubstitute; using Xunit; + namespace NLog.Web.Tests.LayoutRenderers { public class AspNetMvcActionRendererTests : LayoutRenderersTestBase { [Fact] public void NullRoutesRenderersEmptyString() + { + // Arrange + var (renderer, _) = CreateWithHttpContext(); + + // Act + string result = renderer.Render(LogEventInfo.CreateNullEvent()); + + // Assert + Assert.Empty(result); + } + +#if ASP_NET_CORE + [Fact] + public void ActionKeyRendersRouteParameter() { // Arrange var (renderer, httpContext) = CreateWithHttpContext(); - AddRoutingFeature(httpContext); + SetupRouteParameters(httpContext); // Act string result = renderer.Render(LogEventInfo.CreateNullEvent()); // Assert - Assert.Empty(result); + Assert.Equal("actionName", result); } + + private void SetupRouteParameters(HttpContext httpContext) + { + var collection = new FeatureCollection(); + var routeData = new RouteData(); + var routingFeature = Substitute.For(); + collection.Set(routingFeature); +#if ASP_NET_CORE3 + var routingValuesFeature = Substitute.For(); + routingValuesFeature.RouteValues.Returns(routeData.Values); + collection.Set(routingValuesFeature); +#endif + httpContext.Features.Returns(collection); + + routeData.Values.Add("action", "actionName"); + routeData.Values.Add("controller", "controllerName"); + routingFeature.RouteData.Returns(routeData); + } +#endif } } diff --git a/tests/Shared/LayoutRenderers/AspNetMvcControllerRendererTests.cs b/tests/Shared/LayoutRenderers/AspNetMvcControllerRendererTests.cs index 90f12f93..e1e52647 100644 --- a/tests/Shared/LayoutRenderers/AspNetMvcControllerRendererTests.cs +++ b/tests/Shared/LayoutRenderers/AspNetMvcControllerRendererTests.cs @@ -7,8 +7,7 @@ using System.Collections.Specialized; using System.Web.SessionState; #else -using Microsoft.Extensions.Primitives; -using HttpContextBase = Microsoft.AspNetCore.Http.HttpContext; +using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Routing; using Microsoft.AspNetCore.Http.Features; #endif @@ -25,15 +24,48 @@ public class AspNetMvcControllerRendererTests : LayoutRenderersTestBase(); + collection.Set(routingFeature); +#if ASP_NET_CORE3 + var routingValuesFeature = Substitute.For(); + routingValuesFeature.RouteValues.Returns(routeData.Values); + collection.Set(routingValuesFeature); +#endif + httpContext.Features.Returns(collection); + + routeData.Values.Add("action", "actionName"); + routeData.Values.Add("controller", "controllerName"); + routingFeature.RouteData.Returns(routeData); + } +#endif } } diff --git a/tests/Shared/LayoutRenderers/AspNetRequestRouteParametersRendererTests.cs b/tests/Shared/LayoutRenderers/AspNetRequestRouteParametersRendererTests.cs index 04f07e13..cfc79687 100644 --- a/tests/Shared/LayoutRenderers/AspNetRequestRouteParametersRendererTests.cs +++ b/tests/Shared/LayoutRenderers/AspNetRequestRouteParametersRendererTests.cs @@ -1,9 +1,7 @@ using System; using System.Collections.Generic; using NLog.Web.LayoutRenderers; -using NLog.Web.Enums; using Xunit; -using System.Collections.Specialized; using NSubstitute; #if ASP_NET_CORE using Microsoft.AspNetCore.Http; @@ -15,21 +13,6 @@ namespace NLog.Web.Tests.LayoutRenderers { public class AspNetRequestRouteParametersRendererTests : LayoutRenderersTestBase { - [Fact] - public void NullRouteParametersRenderersEmptyString() - { - // Arrange - var (renderer, httpContext) = CreateWithHttpContext(); - - AddRoutingFeature(httpContext); - - // Act - string result = renderer.Render(LogEventInfo.CreateNullEvent()); - - // Assert - Assert.Empty(result); - } - #if ASP_NET_CORE [Fact] public void NullKeyRendersAllRouteParameters() @@ -69,6 +52,11 @@ private void SetupRouteParameters(HttpContext httpContext) var routingFeature = Substitute.For(); var collection = new FeatureCollection(); collection.Set(routingFeature); +#if ASP_NET_CORE3 + var routingValuesFeature = Substitute.For(); + routingValuesFeature.RouteValues.Returns(routeData.Values); + collection.Set(routingValuesFeature); +#endif httpContext.Features.Returns(collection); routeData.Values.Add("key1", "value1"); diff --git a/tests/Shared/LayoutRenderers/AspNetSessionIDLayoutRendererTests.cs b/tests/Shared/LayoutRenderers/AspNetSessionIDLayoutRendererTests.cs index 84119f4c..1ee8639f 100644 --- a/tests/Shared/LayoutRenderers/AspNetSessionIDLayoutRendererTests.cs +++ b/tests/Shared/LayoutRenderers/AspNetSessionIDLayoutRendererTests.cs @@ -3,8 +3,6 @@ using System.Web.Routing; using System.Collections.Specialized; using System.Web.SessionState; -#else -using HttpContextBase = Microsoft.AspNetCore.Http.HttpContext; #endif using NLog.Web.LayoutRenderers; using NSubstitute; diff --git a/tests/Shared/LayoutRenderers/AspNetSessionValueLayoutRendererTests2.cs b/tests/Shared/LayoutRenderers/AspNetSessionValueLayoutRendererTests2.cs index 34ef717c..f0b59ff8 100644 --- a/tests/Shared/LayoutRenderers/AspNetSessionValueLayoutRendererTests2.cs +++ b/tests/Shared/LayoutRenderers/AspNetSessionValueLayoutRendererTests2.cs @@ -92,8 +92,7 @@ private static (AspNetSessionValueLayoutRenderer, HttpContext) CreateRenderer(bo mockSession.SetInt32("b", 123); httpContext.Session = mockSession; httpContext.Items = new Dictionary(); - var sessionFeature = new SessionFeatureMock(mockSession); - httpContext.Features.Get().Returns(sessionFeature); + return (renderer, httpContext); } diff --git a/tests/Shared/LayoutRenderers/LayoutRenderersTestBase.cs b/tests/Shared/LayoutRenderers/LayoutRenderersTestBase.cs index e9638785..a1a466f5 100644 --- a/tests/Shared/LayoutRenderers/LayoutRenderersTestBase.cs +++ b/tests/Shared/LayoutRenderers/LayoutRenderersTestBase.cs @@ -3,6 +3,7 @@ using NSubstitute; using Xunit; #if ASP_NET_CORE +using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http.Features; using Microsoft.AspNetCore.Routing; using HttpContextBase = Microsoft.AspNetCore.Http.HttpContext; @@ -33,10 +34,19 @@ protected virtual void NullRendersEmptyString() Assert.Empty(result); } - protected static (TLayoutRenderer renderer, HttpContextBase httpContext) CreateWithHttpContext() - + protected static (TLayoutRenderer renderer, HttpContextBase httpContext) CreateWithHttpContext() { var httpContext = Substitute.For(); +#if ASP_NET_CORE + var collection = new FeatureCollection(); + var routingFeature = Substitute.For(); + routingFeature.RouteData.Returns(new RouteData()); + collection.Set(routingFeature); + var sessionFeature = Substitute.For(); + sessionFeature.Session.Returns(Substitute.For()); + collection.Set(sessionFeature); + httpContext.Features.Returns(collection); +#endif #if ASP_NET_CORE3 httpContext.Request.RouteValues.Returns(new RouteValueDictionary()); #endif @@ -46,15 +56,5 @@ protected static (TLayoutRenderer renderer, HttpContextBase httpContext) CreateW }; return (renderer, httpContext); } - - protected static void AddRoutingFeature(HttpContextBase httpContext) - { -#if ASP_NET_CORE - var routingFeature = Substitute.For(); - var collection = new FeatureCollection(); - collection.Set(routingFeature); - httpContext.Features.Returns(collection); -#endif - } } } \ No newline at end of file