From 6cd8f8bbf7e6e9983b81294cc5ea5beab6d59026 Mon Sep 17 00:00:00 2001 From: Drew Brasher Date: Thu, 6 Sep 2018 07:10:18 -0500 Subject: [PATCH 1/8] Added aspnet-request-form layout renderer that outputs all or some of the request form collection. --- .../AspNetRequestFormLayoutRenderer.cs | 88 +++++++++++++++++++ NLog.Web/NLog.Web.csproj | 3 + 2 files changed, 91 insertions(+) create mode 100644 NLog.Web.AspNetCore/LayoutRenderers/AspNetRequestFormLayoutRenderer.cs diff --git a/NLog.Web.AspNetCore/LayoutRenderers/AspNetRequestFormLayoutRenderer.cs b/NLog.Web.AspNetCore/LayoutRenderers/AspNetRequestFormLayoutRenderer.cs new file mode 100644 index 00000000..ef1646c7 --- /dev/null +++ b/NLog.Web.AspNetCore/LayoutRenderers/AspNetRequestFormLayoutRenderer.cs @@ -0,0 +1,88 @@ +#if ASP_NET_CORE +using Microsoft.Extensions.Primitives; +#endif +using NLog.LayoutRenderers; +using NLog.Web.Internal; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace NLog.Web.LayoutRenderers +{ + /// + /// ASP.NET Request Form Data + /// + /// + /// Example usage of ${aspnet-request-form}: + /// + /// ${aspnet-request-form} - Produces - All Form Data from the Request with each key/value pair separated by a new line. + /// ${aspnet-request-form:Include=id,name} - Produces - Only Form Data from the Request with keys "id" and "name". + /// ${aspnet-request-form:Exclude=id,name} - Produces - All Form Data from the Request except the keys "id" and "name". + /// ${aspnet-request-form:Separator= / } - Produces - All Form Data from the Request with each key/value pair separated by " / ". + /// + /// + [LayoutRenderer("aspnet-request-form")] + class AspNetRequestFormLayoutRenderer : AspNetLayoutRendererBase + { + /// + /// Gets or sets the form keys to include in the output. If omitted, all are included. + /// + /// + public string Include { get; set; } + + /// + /// Gets or sets the form keys to exclude in the output. If omitted, none are excluded. + /// + /// + public string Exclude { get; set; } + + /// + /// Gets or sets the separator to use between each key/value pair. If omitted, is used. + /// + /// + public string Separator { get; set; } + + /// + /// Renders the Form Collection from the HttpRequest and appends it to the specified . + /// + /// + /// + protected override void DoAppend(StringBuilder builder, LogEventInfo logEvent) + { + var httpRequest = HttpContextAccessor?.HttpContext?.TryGetRequest(); + if (httpRequest == null) + { + return; + } + + if (httpRequest.Form != null) + { + var includeList = Include == null ? new List() : Include.Split(',').ToList(); + var excludeList = Exclude == null ? new List() : Exclude.Split(',').ToList(); + Separator = Separator ?? Environment.NewLine; + var formDataList = new List(); + +#if !ASP_NET_CORE + foreach (string key in httpRequest.Form.AllKeys) + { + if ((!includeList.Any() || includeList.Contains(key)) && !excludeList.Contains(key)) + { + formDataList.Add(httpRequest.Form[key].ToString()); + } + } +#else + foreach (KeyValuePair item in httpRequest.Form) + { + if ((!includeList.Any() || includeList.Contains(item.Key)) && !excludeList.Contains(item.Key)) + { + formDataList.Add(item.ToString()); + } + } +#endif + + builder.Append(string.Join(Separator, formDataList.ToArray())); + } + } + } +} diff --git a/NLog.Web/NLog.Web.csproj b/NLog.Web/NLog.Web.csproj index b99ee61d..3c177816 100644 --- a/NLog.Web/NLog.Web.csproj +++ b/NLog.Web/NLog.Web.csproj @@ -68,6 +68,9 @@ + + AspNetRequestFormLayoutRenderer.cs + From d179da29c4f800a26ab77ba8f4c0490dfc897922 Mon Sep 17 00:00:00 2001 From: Drew Brasher Date: Fri, 7 Sep 2018 07:08:31 -0500 Subject: [PATCH 2/8] Made the aspnet-request-form layout renderer output uniform in both asp.net core and .net --- .../LayoutRenderers/AspNetRequestFormLayoutRenderer.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/NLog.Web.AspNetCore/LayoutRenderers/AspNetRequestFormLayoutRenderer.cs b/NLog.Web.AspNetCore/LayoutRenderers/AspNetRequestFormLayoutRenderer.cs index ef1646c7..0c1d628b 100644 --- a/NLog.Web.AspNetCore/LayoutRenderers/AspNetRequestFormLayoutRenderer.cs +++ b/NLog.Web.AspNetCore/LayoutRenderers/AspNetRequestFormLayoutRenderer.cs @@ -23,7 +23,7 @@ namespace NLog.Web.LayoutRenderers /// /// [LayoutRenderer("aspnet-request-form")] - class AspNetRequestFormLayoutRenderer : AspNetLayoutRendererBase + public class AspNetRequestFormLayoutRenderer : AspNetLayoutRendererBase { /// /// Gets or sets the form keys to include in the output. If omitted, all are included. @@ -68,7 +68,7 @@ protected override void DoAppend(StringBuilder builder, LogEventInfo logEvent) { if ((!includeList.Any() || includeList.Contains(key)) && !excludeList.Contains(key)) { - formDataList.Add(httpRequest.Form[key].ToString()); + formDataList.Add($"{key}={httpRequest.Form[key]}"); } } #else @@ -76,7 +76,7 @@ protected override void DoAppend(StringBuilder builder, LogEventInfo logEvent) { if ((!includeList.Any() || includeList.Contains(item.Key)) && !excludeList.Contains(item.Key)) { - formDataList.Add(item.ToString()); + formDataList.Add($"{item.Key}={item.Value}"); } } #endif From be8f5bf7763d87908b2f096c62793eca4034a6b8 Mon Sep 17 00:00:00 2001 From: Drew Brasher Date: Fri, 7 Sep 2018 07:09:15 -0500 Subject: [PATCH 3/8] Added unit tests for aspnet-request-form layout renderer. --- .../AspNetRequestFormLayoutRendererTests.cs | 123 ++++++++++++++++++ NLog.Web.Tests/NLog.Web.Tests.csproj | 3 + 2 files changed, 126 insertions(+) create mode 100644 NLog.Web.AspNetCore.Tests/LayoutRenderers/AspNetRequestFormLayoutRendererTests.cs diff --git a/NLog.Web.AspNetCore.Tests/LayoutRenderers/AspNetRequestFormLayoutRendererTests.cs b/NLog.Web.AspNetCore.Tests/LayoutRenderers/AspNetRequestFormLayoutRendererTests.cs new file mode 100644 index 00000000..064b46cb --- /dev/null +++ b/NLog.Web.AspNetCore.Tests/LayoutRenderers/AspNetRequestFormLayoutRendererTests.cs @@ -0,0 +1,123 @@ +using NLog.Web.Tests.LayoutRenderers; +using System; +using System.Collections.Generic; +using System.Text; +using NLog.Web.LayoutRenderers; +using NLog.Web.Tests; +using NSubstitute; +using System.Collections.Specialized; +#if ASP_NET_CORE +using Microsoft.AspNetCore.Http; +using Microsoft.Extensions.Primitives; +#else +using System.Web; +#endif +using Xunit; + +namespace NLog.Web.Tests.LayoutRenderers +{ + public class AspNetRequestFormLayoutRendererTests : TestInvolvingAspNetHttpContext + { + [Fact] + public void ShouldReturnEmptyIfFormCollectionIsEmpty() + { + // Arrange + var expectedResult = ""; + var renderer = CreateRenderer(false); + + // Act + string result = renderer.Render(new LogEventInfo()); + + // Assert + Assert.Equal(expectedResult, result); + } + + [Fact] + public void ShouldReturnAllIfDefaultsAreUsed() + { + // Arrange + var expectedResult = "id=1\r\nname=Test Person\r\ntoken=86abe8fe-2237-4f87-81af-0a4e522b4140"; + var renderer = CreateRenderer(); + + // Act + string result = renderer.Render(new LogEventInfo()); + + // Assert + Assert.Equal(expectedResult, result); + } + + [Fact] + public void ShouldReturnOnlySpecifiedIfIncludeIsUsed() + { + // Arrange + var expectedResult = "id=1\r\nname=Test Person"; + var renderer = CreateRenderer(); + renderer.Include = "id,name"; + + // Act + string result = renderer.Render(new LogEventInfo()); + + // Assert + Assert.Equal(expectedResult, result); + } + + [Fact] + public void ShouldNotReturnKeysSpecidiedInExclude() + { + // Arrange + var expectedResult = "id=1\r\nname=Test Person"; + var renderer = CreateRenderer(); + renderer.Exclude = "token"; + + // Act + string result = renderer.Render(new LogEventInfo()); + + // Assert + Assert.Equal(expectedResult, result); + } + + [Fact] + public void ShouldUseTheSpecifiedSeparator() + { + // Arrange + var expectedResult = "id=1 / name=Test Person / token=86abe8fe-2237-4f87-81af-0a4e522b4140"; + var renderer = CreateRenderer(); + renderer.Separator = " / "; + + // Act + string result = renderer.Render(new LogEventInfo()); + + // Assert + Assert.Equal(expectedResult, result); + } + + private AspNetRequestFormLayoutRenderer CreateRenderer(bool hasFormValues = true) + { +#if ASP_NET_CORE + var httpContext = this.HttpContext; +#else + var httpContext = Substitute.For(); +#endif + if (hasFormValues) + { +#if ASP_NET_CORE + var formCollection = new FormCollection(new Dictionary{ + { "id","1" }, + { "name","Test Person" }, + { "token","86abe8fe-2237-4f87-81af-0a4e522b4140" } + }); +#else + var formCollection = new NameValueCollection(){ + { "id","1" }, + { "name","Test Person" }, + { "token","86abe8fe-2237-4f87-81af-0a4e522b4140" } + }; +#endif + httpContext.Request.Form.Returns(formCollection); + } + var renderer = new AspNetRequestFormLayoutRenderer(); + renderer.HttpContextAccessor = new FakeHttpContextAccessor(httpContext); + return renderer; + } + } +} diff --git a/NLog.Web.Tests/NLog.Web.Tests.csproj b/NLog.Web.Tests/NLog.Web.Tests.csproj index 502e6cd0..46b00463 100644 --- a/NLog.Web.Tests/NLog.Web.Tests.csproj +++ b/NLog.Web.Tests/NLog.Web.Tests.csproj @@ -92,6 +92,9 @@ + + AspNetRequestFormLayoutRendererTests.cs + From bf57a368d2948d3450d5bfc773c93f98d2412db9 Mon Sep 17 00:00:00 2001 From: Drew Brasher Date: Fri, 7 Sep 2018 07:43:13 -0500 Subject: [PATCH 4/8] Fixed issues with the unit tests for aspnet-request-form not working in the AspNetCore.Tests project. --- .../LayoutRenderers/AspNetRequestFormLayoutRendererTests.cs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/NLog.Web.AspNetCore.Tests/LayoutRenderers/AspNetRequestFormLayoutRendererTests.cs b/NLog.Web.AspNetCore.Tests/LayoutRenderers/AspNetRequestFormLayoutRendererTests.cs index 064b46cb..e31e3db2 100644 --- a/NLog.Web.AspNetCore.Tests/LayoutRenderers/AspNetRequestFormLayoutRendererTests.cs +++ b/NLog.Web.AspNetCore.Tests/LayoutRenderers/AspNetRequestFormLayoutRendererTests.cs @@ -95,9 +95,12 @@ private AspNetRequestFormLayoutRenderer CreateRenderer(bool hasFormValues = true { #if ASP_NET_CORE var httpContext = this.HttpContext; + httpContext.Request.ContentType = "application/x-www-form-urlencoded"; #else var httpContext = Substitute.For(); + httpContext.Request.ContentType.Returns("application/x-www-form-urlencoded"); #endif + if (hasFormValues) { #if ASP_NET_CORE @@ -106,14 +109,15 @@ private AspNetRequestFormLayoutRenderer CreateRenderer(bool hasFormValues = true { "name","Test Person" }, { "token","86abe8fe-2237-4f87-81af-0a4e522b4140" } }); + httpContext.Request.Form = formCollection; #else var formCollection = new NameValueCollection(){ { "id","1" }, { "name","Test Person" }, { "token","86abe8fe-2237-4f87-81af-0a4e522b4140" } }; -#endif httpContext.Request.Form.Returns(formCollection); +#endif } var renderer = new AspNetRequestFormLayoutRenderer(); renderer.HttpContextAccessor = new FakeHttpContextAccessor(httpContext); From 8b7999a93bc75e3834e21d5cd999824bea184976 Mon Sep 17 00:00:00 2001 From: Drew Brasher Date: Mon, 10 Sep 2018 09:25:24 -0500 Subject: [PATCH 5/8] Removed code duplication by changing to a foreach that works for both AspNetCore and .net framework . --- .../AspNetRequestFormLayoutRenderer.cs | 17 ++--------------- 1 file changed, 2 insertions(+), 15 deletions(-) diff --git a/NLog.Web.AspNetCore/LayoutRenderers/AspNetRequestFormLayoutRenderer.cs b/NLog.Web.AspNetCore/LayoutRenderers/AspNetRequestFormLayoutRenderer.cs index 0c1d628b..e99c69c5 100644 --- a/NLog.Web.AspNetCore/LayoutRenderers/AspNetRequestFormLayoutRenderer.cs +++ b/NLog.Web.AspNetCore/LayoutRenderers/AspNetRequestFormLayoutRenderer.cs @@ -1,7 +1,4 @@ -#if ASP_NET_CORE -using Microsoft.Extensions.Primitives; -#endif -using NLog.LayoutRenderers; +using NLog.LayoutRenderers; using NLog.Web.Internal; using System; using System.Collections.Generic; @@ -63,23 +60,13 @@ protected override void DoAppend(StringBuilder builder, LogEventInfo logEvent) Separator = Separator ?? Environment.NewLine; var formDataList = new List(); -#if !ASP_NET_CORE - foreach (string key in httpRequest.Form.AllKeys) + foreach (string key in httpRequest.Form.Keys) { if ((!includeList.Any() || includeList.Contains(key)) && !excludeList.Contains(key)) { formDataList.Add($"{key}={httpRequest.Form[key]}"); } } -#else - foreach (KeyValuePair item in httpRequest.Form) - { - if ((!includeList.Any() || includeList.Contains(item.Key)) && !excludeList.Contains(item.Key)) - { - formDataList.Add($"{item.Key}={item.Value}"); - } - } -#endif builder.Append(string.Join(Separator, formDataList.ToArray())); } From 8eb037049c212c70d2b85668883788d0565d5bb4 Mon Sep 17 00:00:00 2001 From: Drew Brasher Date: Mon, 10 Sep 2018 14:41:51 -0500 Subject: [PATCH 6/8] Changed Include and Exclude to case insensitive HashSets. --- .../AspNetRequestFormLayoutRendererTests.cs | 5 ++-- .../AspNetRequestFormLayoutRenderer.cs | 27 ++++++++++++++----- 2 files changed, 24 insertions(+), 8 deletions(-) diff --git a/NLog.Web.AspNetCore.Tests/LayoutRenderers/AspNetRequestFormLayoutRendererTests.cs b/NLog.Web.AspNetCore.Tests/LayoutRenderers/AspNetRequestFormLayoutRendererTests.cs index e31e3db2..274f8a46 100644 --- a/NLog.Web.AspNetCore.Tests/LayoutRenderers/AspNetRequestFormLayoutRendererTests.cs +++ b/NLog.Web.AspNetCore.Tests/LayoutRenderers/AspNetRequestFormLayoutRendererTests.cs @@ -52,7 +52,8 @@ public void ShouldReturnOnlySpecifiedIfIncludeIsUsed() // Arrange var expectedResult = "id=1\r\nname=Test Person"; var renderer = CreateRenderer(); - renderer.Include = "id,name"; + renderer.Include.Add("id"); + renderer.Include.Add("name"); // Act string result = renderer.Render(new LogEventInfo()); @@ -67,7 +68,7 @@ public void ShouldNotReturnKeysSpecidiedInExclude() // Arrange var expectedResult = "id=1\r\nname=Test Person"; var renderer = CreateRenderer(); - renderer.Exclude = "token"; + renderer.Exclude.Add("token"); // Act string result = renderer.Render(new LogEventInfo()); diff --git a/NLog.Web.AspNetCore/LayoutRenderers/AspNetRequestFormLayoutRenderer.cs b/NLog.Web.AspNetCore/LayoutRenderers/AspNetRequestFormLayoutRenderer.cs index e99c69c5..2cf74f4f 100644 --- a/NLog.Web.AspNetCore/LayoutRenderers/AspNetRequestFormLayoutRenderer.cs +++ b/NLog.Web.AspNetCore/LayoutRenderers/AspNetRequestFormLayoutRenderer.cs @@ -26,13 +26,21 @@ public class AspNetRequestFormLayoutRenderer : AspNetLayoutRendererBase /// Gets or sets the form keys to include in the output. If omitted, all are included. /// /// - public string Include { get; set; } +#if ASP_NET_CORE + public ISet Include { get; set; } +#else + public HashSet Include { get; set; } +#endif /// - /// Gets or sets the form keys to exclude in the output. If omitted, none are excluded. + /// Gets or sets the form keys to exclude from the output. If omitted, none are excluded. /// /// - public string Exclude { get; set; } +#if ASP_NET_CORE + public ISet Exclude { get; set; } +#else + public HashSet Exclude { get; set; } +#endif /// /// Gets or sets the separator to use between each key/value pair. If omitted, is used. @@ -40,6 +48,15 @@ public class AspNetRequestFormLayoutRenderer : AspNetLayoutRendererBase /// public string Separator { get; set; } + /// + /// Constructor + /// + public AspNetRequestFormLayoutRenderer() + { + Include = new HashSet(StringComparer.OrdinalIgnoreCase); + Exclude = new HashSet(StringComparer.OrdinalIgnoreCase); + } + /// /// Renders the Form Collection from the HttpRequest and appends it to the specified . /// @@ -55,14 +72,12 @@ protected override void DoAppend(StringBuilder builder, LogEventInfo logEvent) if (httpRequest.Form != null) { - var includeList = Include == null ? new List() : Include.Split(',').ToList(); - var excludeList = Exclude == null ? new List() : Exclude.Split(',').ToList(); Separator = Separator ?? Environment.NewLine; var formDataList = new List(); foreach (string key in httpRequest.Form.Keys) { - if ((!includeList.Any() || includeList.Contains(key)) && !excludeList.Contains(key)) + if ((!Include.Any() || Include.Contains(key)) && !Exclude.Contains(key)) { formDataList.Add($"{key}={httpRequest.Form[key]}"); } From 729e1bcc8486a19de66f7bd376053659984491b1 Mon Sep 17 00:00:00 2001 From: Drew Brasher Date: Wed, 19 Sep 2018 12:41:35 -0500 Subject: [PATCH 7/8] Added unit test to cove exclude/include precedence and updated comments. --- .../AspNetRequestFormLayoutRendererTests.cs | 25 ++++++++++++++++--- .../AspNetRequestFormLayoutRenderer.cs | 5 ++-- 2 files changed, 25 insertions(+), 5 deletions(-) diff --git a/NLog.Web.AspNetCore.Tests/LayoutRenderers/AspNetRequestFormLayoutRendererTests.cs b/NLog.Web.AspNetCore.Tests/LayoutRenderers/AspNetRequestFormLayoutRendererTests.cs index 274f8a46..c82449de 100644 --- a/NLog.Web.AspNetCore.Tests/LayoutRenderers/AspNetRequestFormLayoutRendererTests.cs +++ b/NLog.Web.AspNetCore.Tests/LayoutRenderers/AspNetRequestFormLayoutRendererTests.cs @@ -92,6 +92,23 @@ public void ShouldUseTheSpecifiedSeparator() Assert.Equal(expectedResult, result); } + [Fact] + public void ExcludeShouldTakePrecedenceOverInclude() + { + // Arrange + var expectedResult = "name=Test Person"; + var renderer = CreateRenderer(); + renderer.Include.Add("id"); + renderer.Include.Add("name"); + renderer.Exclude.Add("id"); + + // Act + string result = renderer.Render(new LogEventInfo()); + + // Assert + Assert.Equal(expectedResult, result); + } + private AspNetRequestFormLayoutRenderer CreateRenderer(bool hasFormValues = true) { #if ASP_NET_CORE @@ -120,9 +137,11 @@ private AspNetRequestFormLayoutRenderer CreateRenderer(bool hasFormValues = true httpContext.Request.Form.Returns(formCollection); #endif } - var renderer = new AspNetRequestFormLayoutRenderer(); - renderer.HttpContextAccessor = new FakeHttpContextAccessor(httpContext); - return renderer; + + return new AspNetRequestFormLayoutRenderer + { + HttpContextAccessor = new FakeHttpContextAccessor(httpContext) + }; } } } diff --git a/NLog.Web.AspNetCore/LayoutRenderers/AspNetRequestFormLayoutRenderer.cs b/NLog.Web.AspNetCore/LayoutRenderers/AspNetRequestFormLayoutRenderer.cs index 2cf74f4f..5ee99407 100644 --- a/NLog.Web.AspNetCore/LayoutRenderers/AspNetRequestFormLayoutRenderer.cs +++ b/NLog.Web.AspNetCore/LayoutRenderers/AspNetRequestFormLayoutRenderer.cs @@ -16,6 +16,7 @@ namespace NLog.Web.LayoutRenderers /// ${aspnet-request-form} - Produces - All Form Data from the Request with each key/value pair separated by a new line. /// ${aspnet-request-form:Include=id,name} - Produces - Only Form Data from the Request with keys "id" and "name". /// ${aspnet-request-form:Exclude=id,name} - Produces - All Form Data from the Request except the keys "id" and "name". + /// ${aspnet-request-form:Include=id,name:Exclude=id} - Produces - Only Form Data from the Request with key "name" ( takes precedence over ). /// ${aspnet-request-form:Separator= / } - Produces - All Form Data from the Request with each key/value pair separated by " / ". /// /// @@ -23,7 +24,7 @@ namespace NLog.Web.LayoutRenderers public class AspNetRequestFormLayoutRenderer : AspNetLayoutRendererBase { /// - /// Gets or sets the form keys to include in the output. If omitted, all are included. + /// Gets or sets the form keys to include in the output. If omitted, all are included. takes precedence over . /// /// #if ASP_NET_CORE @@ -33,7 +34,7 @@ public class AspNetRequestFormLayoutRenderer : AspNetLayoutRendererBase #endif /// - /// Gets or sets the form keys to exclude from the output. If omitted, none are excluded. + /// Gets or sets the form keys to exclude from the output. If omitted, none are excluded. takes precedence over . /// /// #if ASP_NET_CORE From a842581ea5b4e8df86e6f33164a66aeb7b49e698 Mon Sep 17 00:00:00 2001 From: Drew Brasher Date: Sat, 22 Sep 2018 15:40:28 -0500 Subject: [PATCH 8/8] Made AspNetRequestFormLayoutRenderer a subclass of AspNetLayoutMultiValueRendererBase --- .../AspNetRequestFormLayoutRendererTests.cs | 10 ++--- .../AspNetRequestFormLayoutRenderer.cs | 37 ++++++++++--------- 2 files changed, 25 insertions(+), 22 deletions(-) diff --git a/NLog.Web.AspNetCore.Tests/LayoutRenderers/AspNetRequestFormLayoutRendererTests.cs b/NLog.Web.AspNetCore.Tests/LayoutRenderers/AspNetRequestFormLayoutRendererTests.cs index c82449de..06bac6ff 100644 --- a/NLog.Web.AspNetCore.Tests/LayoutRenderers/AspNetRequestFormLayoutRendererTests.cs +++ b/NLog.Web.AspNetCore.Tests/LayoutRenderers/AspNetRequestFormLayoutRendererTests.cs @@ -36,7 +36,7 @@ public void ShouldReturnEmptyIfFormCollectionIsEmpty() public void ShouldReturnAllIfDefaultsAreUsed() { // Arrange - var expectedResult = "id=1\r\nname=Test Person\r\ntoken=86abe8fe-2237-4f87-81af-0a4e522b4140"; + var expectedResult = "id=1,name=Test Person,token=86abe8fe-2237-4f87-81af-0a4e522b4140"; var renderer = CreateRenderer(); // Act @@ -50,7 +50,7 @@ public void ShouldReturnAllIfDefaultsAreUsed() public void ShouldReturnOnlySpecifiedIfIncludeIsUsed() { // Arrange - var expectedResult = "id=1\r\nname=Test Person"; + var expectedResult = "id=1,name=Test Person"; var renderer = CreateRenderer(); renderer.Include.Add("id"); renderer.Include.Add("name"); @@ -66,7 +66,7 @@ public void ShouldReturnOnlySpecifiedIfIncludeIsUsed() public void ShouldNotReturnKeysSpecidiedInExclude() { // Arrange - var expectedResult = "id=1\r\nname=Test Person"; + var expectedResult = "id=1,name=Test Person"; var renderer = CreateRenderer(); renderer.Exclude.Add("token"); @@ -81,9 +81,9 @@ public void ShouldNotReturnKeysSpecidiedInExclude() public void ShouldUseTheSpecifiedSeparator() { // Arrange - var expectedResult = "id=1 / name=Test Person / token=86abe8fe-2237-4f87-81af-0a4e522b4140"; + var expectedResult = "id=1\r\nname=Test Person\r\ntoken=86abe8fe-2237-4f87-81af-0a4e522b4140"; var renderer = CreateRenderer(); - renderer.Separator = " / "; + renderer.ItemSeparator = "${newline}"; // Act string result = renderer.Render(new LogEventInfo()); diff --git a/NLog.Web.AspNetCore/LayoutRenderers/AspNetRequestFormLayoutRenderer.cs b/NLog.Web.AspNetCore/LayoutRenderers/AspNetRequestFormLayoutRenderer.cs index 5ee99407..60f105f1 100644 --- a/NLog.Web.AspNetCore/LayoutRenderers/AspNetRequestFormLayoutRenderer.cs +++ b/NLog.Web.AspNetCore/LayoutRenderers/AspNetRequestFormLayoutRenderer.cs @@ -13,15 +13,15 @@ namespace NLog.Web.LayoutRenderers /// /// Example usage of ${aspnet-request-form}: /// - /// ${aspnet-request-form} - Produces - All Form Data from the Request with each key/value pair separated by a new line. + /// ${aspnet-request-form} - Produces - All Form Data from the Request with each key/value pair separated by a comma. /// ${aspnet-request-form:Include=id,name} - Produces - Only Form Data from the Request with keys "id" and "name". /// ${aspnet-request-form:Exclude=id,name} - Produces - All Form Data from the Request except the keys "id" and "name". /// ${aspnet-request-form:Include=id,name:Exclude=id} - Produces - Only Form Data from the Request with key "name" ( takes precedence over ). - /// ${aspnet-request-form:Separator= / } - Produces - All Form Data from the Request with each key/value pair separated by " / ". + /// ${aspnet-request-form:ItemSeparator=${newline}} - Produces - All Form Data from the Request with each key/value pair separated by a new line. /// /// [LayoutRenderer("aspnet-request-form")] - public class AspNetRequestFormLayoutRenderer : AspNetLayoutRendererBase + public class AspNetRequestFormLayoutRenderer : AspNetLayoutMultiValueRendererBase { /// /// Gets or sets the form keys to include in the output. If omitted, all are included. takes precedence over . @@ -43,12 +43,6 @@ public class AspNetRequestFormLayoutRenderer : AspNetLayoutRendererBase public HashSet Exclude { get; set; } #endif - /// - /// Gets or sets the separator to use between each key/value pair. If omitted, is used. - /// - /// - public string Separator { get; set; } - /// /// Constructor /// @@ -65,27 +59,36 @@ public AspNetRequestFormLayoutRenderer() /// protected override void DoAppend(StringBuilder builder, LogEventInfo logEvent) { - var httpRequest = HttpContextAccessor?.HttpContext?.TryGetRequest(); - if (httpRequest == null) + if (HttpContextAccessor?.HttpContext?.TryGetRequest() == null) { return; } - if (httpRequest.Form != null) + var formDataToInclude = GetPairsToInclude(); + + if (formDataToInclude.Any()) { - Separator = Separator ?? Environment.NewLine; - var formDataList = new List(); + SerializePairs(formDataToInclude, builder, logEvent); + } + } + + private IEnumerable> GetPairsToInclude() + { + var httpRequest = HttpContextAccessor?.HttpContext?.TryGetRequest(); + var pairs = new List>(); + if (httpRequest.Form != null) + { foreach (string key in httpRequest.Form.Keys) { if ((!Include.Any() || Include.Contains(key)) && !Exclude.Contains(key)) { - formDataList.Add($"{key}={httpRequest.Form[key]}"); + pairs.Add(new KeyValuePair(key, httpRequest.Form[key])); } } - - builder.Append(string.Join(Separator, formDataList.ToArray())); } + + return pairs; } } }