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 Oct 28, 2021
1 parent 185f7d4 commit eba1225
Show file tree
Hide file tree
Showing 8 changed files with 127 additions and 114 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,
}
}
101 changes: 45 additions & 56 deletions src/Shared/LayoutRenderers/AspNetLayoutMultiValueRendererBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,45 +12,36 @@ namespace NLog.Web.LayoutRenderers
/// </summary>
public abstract class AspNetLayoutMultiValueRendererBase : AspNetLayoutRendererBase
{
private string _itemSeparator = ",";
private Layout _itemSeparatorLayout = ",";
private string _valueSeparator = "=";
private Layout _valueSeparatorLayout = "=";

/// <summary>
/// Separator between item. Only used for <see cref="AspNetRequestLayoutOutputFormat.Flat" />
/// </summary>
/// <remarks>Render with <see cref="GetRenderedItemSeparator" /></remarks>
public string ItemSeparator
{
get => _itemSeparator;
set
{
_itemSeparator = value;
_itemSeparatorLayout = value;
}
}
public string ItemSeparator { get => _itemSeparatorLayout?.OriginalText; set => _itemSeparatorLayout = new SimpleLayout(value ?? ""); }
private SimpleLayout _itemSeparatorLayout = new SimpleLayout(",");

/// <summary>
/// Separator between value and key. Only used for <see cref="AspNetRequestLayoutOutputFormat.Flat" />
/// </summary>
/// <remarks>Render with <see cref="GetRenderedValueSeparator" /></remarks>
public string ValueSeparator
public string ValueSeparator { get => _valueSeparatorLayout?.OriginalText; set => _valueSeparatorLayout = new SimpleLayout(value ?? ""); }
private SimpleLayout _valueSeparatorLayout = new SimpleLayout("=");

/// <summary>
/// Get or set whether single key/value-pair be rendered as Json-Array.
/// </summary>
[Obsolete("Replaced by OutputFormat = JsonArray / JsonDictionary. Marked obsolete with NLog.Web ver. 5.0")]
public bool SingleAsArray
{
get => _valueSeparator;
get => OutputFormat != AspNetRequestLayoutOutputFormat.JsonDictionary;
set
{
_valueSeparator = value;
_valueSeparatorLayout = value;
if (!value)
OutputFormat = AspNetRequestLayoutOutputFormat.JsonDictionary;
else if (OutputFormat == AspNetRequestLayoutOutputFormat.JsonDictionary)
OutputFormat = AspNetRequestLayoutOutputFormat.JsonArray;
}
}

/// <summary>
/// Single item in array? Only used for <see cref="AspNetRequestLayoutOutputFormat.Json" />
/// Mutliple items are always in an array.
/// </summary>
public bool SingleAsArray { get; set; } = true;

/// <summary>
/// Determines how the output is rendered. Possible Value: FLAT, JSON. Default is FLAT.
/// </summary>
Expand All @@ -61,17 +52,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 +65,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 +75,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)
foreach (var item in pairs)
{
builder.Append('[');
}

foreach (var kpv in pairsList)
{
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 +120,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
/// <para>Example usage of ${aspnet-request-cookie}</para>
/// <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 @@ -93,7 +94,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
/// <para>Example usage of ${aspnet-request-headers}</para>
/// <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
/// <para>Example usage of ${aspnet-request-querystring}:</para>
/// <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
47 changes: 26 additions & 21 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 @@ -130,7 +128,7 @@ public void KeyFoundRendersValue_Single_Cookie_Json_Formatting()
var expectedResult = "[{\"key\":\"TEST\"}]";

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

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

Expand All @@ -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;
renderer.OutputFormat = AspNetRequestLayoutOutputFormat.JsonArray;

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 All @@ -184,7 +191,7 @@ public void KeyNotFoundRendersEmptyString_Flat_Formatting_ValuesOnly()
public void KeyNotFoundRendersEmptyString_Json_Formatting_ValuesOnly()
{
var renderer = CreateRenderer();
renderer.OutputFormat = AspNetRequestLayoutOutputFormat.Json;
renderer.OutputFormat = AspNetRequestLayoutOutputFormat.JsonArray;
renderer.CookieNames = new List<string> { "notfound" };
renderer.ValuesOnly = true;

Expand Down Expand Up @@ -240,7 +247,7 @@ public void KeyFoundRendersValue_Single_Item_Json_Formatting_ValuesOnly()
var expectedResult = "[\"TEST\"]";

var renderer = CreateRenderer(addSecondCookie: false);
renderer.OutputFormat = AspNetRequestLayoutOutputFormat.Json;
renderer.OutputFormat = AspNetRequestLayoutOutputFormat.JsonArray;
renderer.ValuesOnly = true;

string result = renderer.Render(new LogEventInfo());
Expand All @@ -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 Expand Up @@ -304,7 +309,7 @@ public void KeyFoundRendersValue_Multiple_Cookies_And_Cookie_Values_Json_Formatt
{
var expectedResult = "[{\"key\":\"TEST\"},{\"Key1\":\"TEST1\"},{\"key2\":\"Test\"},{\"key3\":\"Test456\"}]";
var renderer = CreateRenderer(addSecondCookie: true, addMultiValueCookieKey: true);
renderer.OutputFormat = AspNetRequestLayoutOutputFormat.Json;
renderer.OutputFormat = AspNetRequestLayoutOutputFormat.JsonArray;

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

Expand Down Expand Up @@ -347,7 +352,7 @@ public void CommaSeperatedCookieNamesTest_Multiple_Cookie_Values_Json_Formatting
var layoutRender = new AspNetRequestCookieLayoutRenderer()
{
CookieNames = new List<string> { "key", "key1" },
OutputFormat = AspNetRequestLayoutOutputFormat.Json
OutputFormat = AspNetRequestLayoutOutputFormat.JsonArray
};

var httpContextAccessorMock = CreateHttpContextAccessorMockWithCookie(cookie);
Expand Down
Loading

0 comments on commit eba1225

Please sign in to comment.