Skip to content

Commit

Permalink
Replaced SingleAsArray with OutputFormat = JsonArray + JsonDictionary
Browse files Browse the repository at this point in the history
  • Loading branch information
snakefoot committed Sep 25, 2021
1 parent b98cd07 commit a8e8759
Show file tree
Hide file tree
Showing 8 changed files with 109 additions and 77 deletions.
15 changes: 14 additions & 1 deletion src/Shared/Enums/AspNetRequestLayoutOutputFormat.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
using System;

namespace NLog.Web.Enums
{
/// <summary>
Expand All @@ -10,9 +12,20 @@ public enum AspNetRequestLayoutOutputFormat
/// </summary>
Flat = 0,

/// <summary>
/// Use this format for rendering the output value as a json-array
/// </summary>
JsonArray = 1,

/// <summary>
/// Use this format for rendering the output value as a json formatted string.
/// </summary>
Json = 1
[Obsolete("Replaced by JsonArray. Marked obsolete with NLog 5.0")]
Json = 1,

/// <summary>
/// Use this format for rendering the output value as a json-dictionary
/// </summary>
JsonDictionary = 2,
}
}
78 changes: 43 additions & 35 deletions src/Shared/LayoutRenderers/AspNetLayoutMultiValueRendererBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -46,10 +46,20 @@ public string ValueSeparator
}

/// <summary>
/// Single item in array? Only used for <see cref="AspNetRequestLayoutOutputFormat.Json" />
/// Mutliple items are always in an array.
/// Get or set whether single key/value-pair be rendered as Json-Array.
/// </summary>
public bool SingleAsArray { get; set; } = true;
[Obsolete("Replaced by OutputFormat = JsonArray / JsonDictionary. Marked obsolete with NLog.Web ver. 5.0")]
public bool SingleAsArray
{
get => OutputFormat != AspNetRequestLayoutOutputFormat.JsonDictionary;
set
{
if (!value)
OutputFormat = AspNetRequestLayoutOutputFormat.JsonDictionary;
else if (OutputFormat == AspNetRequestLayoutOutputFormat.JsonDictionary)
OutputFormat = AspNetRequestLayoutOutputFormat.JsonArray;
}
}

/// <summary>
/// Determines how the output is rendered. Possible Value: FLAT, JSON. Default is FLAT.
Expand All @@ -61,17 +71,6 @@ public string ValueSeparator
/// </summary>
public bool ValuesOnly { get; set; }

/// <summary>
/// Serialize multiple key/value pairs
/// </summary>
/// <param name="pairs">The key/value pairs.</param>
/// <param name="builder">Add to this builder.</param>
[Obsolete("use SerializePairs with logEvent to support Layouts for Separator. This overload will be removed in NLog.Web(aspNetCore) 5")]
protected void SerializePairs(IEnumerable<KeyValuePair<string, string>> pairs, StringBuilder builder)
{
SerializePairs(pairs, builder, null);
}

/// <summary>
/// Serialize multiple key/value pairs
/// </summary>
Expand All @@ -85,7 +84,8 @@ protected void SerializePairs(IEnumerable<KeyValuePair<string, string>> pairs, S
case AspNetRequestLayoutOutputFormat.Flat:
SerializePairsFlat(pairs, builder, logEvent);
break;
case AspNetRequestLayoutOutputFormat.Json:
case AspNetRequestLayoutOutputFormat.JsonArray:
case AspNetRequestLayoutOutputFormat.JsonDictionary:
SerializePairsJson(pairs, builder);
break;
}
Expand All @@ -94,35 +94,40 @@ protected void SerializePairs(IEnumerable<KeyValuePair<string, string>> pairs, S
private void SerializePairsJson(IEnumerable<KeyValuePair<string, string>> pairs, StringBuilder builder)
{
var firstItem = true;
var pairsList = pairs.ToList();

if (pairsList.Count == 0)
{
return;
}

var addArray = pairsList.Count > (SingleAsArray || ValuesOnly ? 0 : 1);

if (addArray)
{
builder.Append('[');
}

foreach (var kpv in pairsList)
foreach (var item in pairs)
{
if (!firstItem)
if (firstItem)
{
if (!ValuesOnly && OutputFormat == AspNetRequestLayoutOutputFormat.JsonDictionary)
{
builder.Append("{");
}
else
{
builder.Append("[");
}
}
else
{
builder.Append(',');
}

SerializePairJson(builder, kpv);
SerializePairJson(builder, item);

firstItem = false;
}

if (addArray)
if (!firstItem)
{
builder.Append(']');
if (!ValuesOnly && OutputFormat == AspNetRequestLayoutOutputFormat.JsonDictionary)
{
builder.Append("}");
}
else
{
builder.Append("]");
}
}
}

Expand All @@ -134,15 +139,18 @@ private void SerializePairJson(StringBuilder builder, KeyValuePair<string, strin
if (!ValuesOnly)
{
// Quoted key
builder.Append('{');
if (OutputFormat != AspNetRequestLayoutOutputFormat.JsonDictionary)
{
builder.Append('{');
}
AppendQuoted(builder, key);
builder.Append(':');
}

// Quoted value
AppendQuoted(builder, value);

if (!ValuesOnly)
if (!ValuesOnly && OutputFormat != AspNetRequestLayoutOutputFormat.JsonDictionary)
{
builder.Append('}');
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,10 @@ namespace NLog.Web.LayoutRenderers
/// <example>
/// <code lang="NLog Layout Renderer">
/// ${aspnet-request-cookie:OutputFormat=Flat}
/// ${aspnet-request-cookie:OutputFormat=Json}
/// ${aspnet-request-cookie:OutputFormat=Json:CookieNames=username}
/// ${aspnet-request-cookie:OutputFormat=Json:Exclude=access_token}
/// ${aspnet-request-cookie:OutputFormat=JsonArray}
/// ${aspnet-request-cookie:OutputFormat=JsonDictionary}
/// ${aspnet-request-cookie:OutputFormat=JsonDictionary:CookieNames=username}
/// ${aspnet-request-cookie:OutputFormat=JsonDictionary:Exclude=access_token}
/// </code>
/// </example>
[LayoutRenderer("aspnet-request-cookie")]
Expand Down Expand Up @@ -94,7 +95,7 @@ private IEnumerable<KeyValuePair<string, string>> GetCookieValues(HttpCookieColl
continue;
}

if (OutputFormat == AspNetRequestLayoutOutputFormat.Json)
if (OutputFormat != AspNetRequestLayoutOutputFormat.Flat)
{
// Split multi-valued cookie, as allowed for in the HttpCookie API for backwards compatibility with classic ASP
var isFirst = true;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,10 @@ namespace NLog.Web.LayoutRenderers
/// <example>
/// <code lang="NLog Layout Renderer">
/// ${aspnet-request-headers:OutputFormat=Flat}
/// ${aspnet-request-headers:OutputFormat=Json}
/// ${aspnet-request-headers:OutputFormat=Json:HeaderNames=username}
/// ${aspnet-request-headers:OutputFormat=Json:Exclude=access_token}
/// ${aspnet-request-headers:OutputFormat=JsonArray}
/// ${aspnet-request-headers:OutputFormat=JsonDictionary}
/// ${aspnet-request-headers:OutputFormat=JsonDictionary:HeaderNames=username}
/// ${aspnet-request-headers:OutputFormat=JsonDictionary:Exclude=access_token}
/// </code>
/// </example>
[LayoutRenderer("aspnet-request-headers")]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@ namespace NLog.Web.LayoutRenderers
/// <example>
/// <code lang="NLog Layout Renderer">
/// ${aspnet-request-querystring:OutputFormat=Flat}
/// ${aspnet-request-querystring:OutputFormat=Json}
/// ${aspnet-request-querystring:OutputFormat=JsonArray}
/// ${aspnet-request-querystring:OutputFormat=JsonDictionary}
/// </code>
/// </example>
[LayoutRenderer("aspnet-request-querystring")]
Expand Down
35 changes: 20 additions & 15 deletions tests/Shared/LayoutRenderers/AspNetCookieLayoutRendererTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,6 @@
using Microsoft.Extensions.Primitives;
#endif



namespace NLog.Web.Tests.LayoutRenderers
{
public class AspNetCookieLayoutRendererTests : TestInvolvingAspNetHttpContext
Expand Down Expand Up @@ -59,7 +57,7 @@ public void KeyNotFoundRendersEmptyString_Flat_Formatting()
public void KeyNotFoundRendersEmptyString_Json_Formatting()
{
var renderer = CreateRenderer();
renderer.OutputFormat = AspNetRequestLayoutOutputFormat.Json;
renderer.OutputFormat = AspNetRequestLayoutOutputFormat.JsonArray;
renderer.CookieNames = new List<string> { "notfound" };

string result = renderer.Render(new LogEventInfo());
Expand Down Expand Up @@ -143,24 +141,33 @@ public void KeyFoundRendersValue_Single_Cookie_Json_Formatting_no_array()
var expectedResult = "{\"key\":\"TEST\"}";

var renderer = CreateRenderer(addSecondCookie: false);
renderer.OutputFormat = AspNetRequestLayoutOutputFormat.Json;
renderer.SingleAsArray = false;
renderer.OutputFormat = AspNetRequestLayoutOutputFormat.JsonDictionary;

string result = renderer.Render(new LogEventInfo());

Assert.Equal(expectedResult, result);
}

[Theory]
[InlineData(false)]
[InlineData(true)]
public void KeyFoundRendersValue_Multiple_Cookies_Json_Formatting(bool singleAsArray)
[Fact]
public void KeyFoundRendersValue_Multiple_Cookies_Json_Formatting()
{
var expectedResult = "[{\"key\":\"TEST\"},{\"Key1\":\"TEST1\"}]";

var renderer = CreateRenderer();
renderer.OutputFormat = AspNetRequestLayoutOutputFormat.Json;
renderer.SingleAsArray = singleAsArray;

string result = renderer.Render(new LogEventInfo());

Assert.Equal(expectedResult, result);
}

[Fact]
public void KeyFoundRendersValue_Multiple_Cookies_Json_Formatting_no_array()
{
var expectedResult = "{\"key\":\"TEST\",\"Key1\":\"TEST1\"}";

var renderer = CreateRenderer();
renderer.OutputFormat = AspNetRequestLayoutOutputFormat.JsonDictionary;

string result = renderer.Render(new LogEventInfo());

Expand Down Expand Up @@ -256,8 +263,7 @@ public void KeyFoundRendersValue_Single_Item_Json_Formatting_no_array_ValuesOnly

var renderer = CreateRenderer(addSecondCookie: false);

renderer.OutputFormat = AspNetRequestLayoutOutputFormat.Json;
renderer.SingleAsArray = false;
renderer.OutputFormat = AspNetRequestLayoutOutputFormat.JsonDictionary;
renderer.ValuesOnly = true;

string result = renderer.Render(new LogEventInfo());
Expand All @@ -268,14 +274,13 @@ public void KeyFoundRendersValue_Single_Item_Json_Formatting_no_array_ValuesOnly
[Theory]
[InlineData(false)]
[InlineData(true)]
public void KeyFoundRendersValue_Cookie_Multiple_Items_Json_Formatting_ValuesOnly(bool singleAsArray)
public void KeyFoundRendersValue_Cookie_Multiple_Items_Json_Formatting_ValuesOnly(bool valuesAsProperties)
{
var expectedResult = "[\"TEST\",\"TEST1\"]";

var renderer = CreateRenderer();

renderer.OutputFormat = AspNetRequestLayoutOutputFormat.Json;
renderer.SingleAsArray = singleAsArray;
renderer.OutputFormat = AspNetRequestLayoutOutputFormat.JsonDictionary;
renderer.ValuesOnly = true;

string result = renderer.Render(new LogEventInfo());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -152,14 +152,12 @@ public void MultipleValuesForOneKeyShouldWork()
[Fact]
public void MultipleValuesJsonQuoted()
{

var expectedResult = @"{""Id"":""a'b,\""c\""""}";

var renderer = CreateAndMockRenderer(CreateTuple("Id", "a'b", "\"c\""));

renderer.QueryStringKeys = null;
renderer.OutputFormat = AspNetRequestLayoutOutputFormat.Json;
renderer.SingleAsArray = false;
renderer.OutputFormat = AspNetRequestLayoutOutputFormat.JsonDictionary;

string result = renderer.Render(new LogEventInfo());

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -141,24 +141,33 @@ public void KeyFoundRendersValue_Single_Header_Json_Formatting_no_array()
var expectedResult = "{\"key\":\"TEST\"}";

var renderer = CreateRenderer(addSecondHeader: false);
renderer.OutputFormat = AspNetRequestLayoutOutputFormat.Json;
renderer.SingleAsArray = false;
renderer.OutputFormat = AspNetRequestLayoutOutputFormat.JsonDictionary;

string result = renderer.Render(new LogEventInfo());

Assert.Equal(expectedResult, result);
}

[Theory]
[InlineData(false)]
[InlineData(true)]
public void KeyFoundRendersValue_Multiple_Headers_Json_Formatting(bool singleAsArray)
[Fact]
public void KeyFoundRendersValue_Multiple_Headers_Json_Formatting()
{
var expectedResult = "[{\"key\":\"TEST\"},{\"Key1\":\"TEST1\"}]";

var renderer = CreateRenderer();
renderer.OutputFormat = AspNetRequestLayoutOutputFormat.Json;
renderer.SingleAsArray = singleAsArray;

string result = renderer.Render(new LogEventInfo());

Assert.Equal(expectedResult, result);
}

[Fact]
public void KeyFoundRendersValue_Multiple_Headers_Json_Formatting_no_array()
{
var expectedResult = "{\"key\":\"TEST\",\"Key1\":\"TEST1\"}";

var renderer = CreateRenderer();
renderer.OutputFormat = AspNetRequestLayoutOutputFormat.JsonDictionary;

string result = renderer.Render(new LogEventInfo());

Expand Down Expand Up @@ -254,26 +263,22 @@ public void KeyFoundRendersValue_Single_Item_Json_Formatting_no_array_ValuesOnly

var renderer = CreateRenderer(addSecondHeader: false);

renderer.OutputFormat = AspNetRequestLayoutOutputFormat.Json;
renderer.SingleAsArray = false;
renderer.OutputFormat = AspNetRequestLayoutOutputFormat.JsonDictionary;
renderer.ValuesOnly = true;

string result = renderer.Render(new LogEventInfo());

Assert.Equal(expectedResult, result);
}

[Theory]
[InlineData(false)]
[InlineData(true)]
public void KeyFoundRendersValue_Header_Multiple_Items_Json_Formatting_ValuesOnly(bool singleAsArray)
[Fact]
public void KeyFoundRendersValue_Header_Multiple_Items_Json_Formatting_ValuesOnly()
{
var expectedResult = "[\"TEST\",\"TEST1\"]";

var renderer = CreateRenderer();

renderer.OutputFormat = AspNetRequestLayoutOutputFormat.Json;
renderer.SingleAsArray = singleAsArray;
renderer.OutputFormat = AspNetRequestLayoutOutputFormat.JsonDictionary;
renderer.ValuesOnly = true;

string result = renderer.Render(new LogEventInfo());
Expand Down

0 comments on commit a8e8759

Please sign in to comment.