diff --git a/appveyor.yml b/appveyor.yml index 81230eb6..bdcc5312 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -21,7 +21,7 @@ build_script: deploy: - provider: NuGet api_key: - secure: 5tuxbM+Ujp0ZtaDCGYET23qKr6bJWo/Vzxlf7uTbspaf8R1R7sIe1JqSDHZoK1gV + secure: e+0IpLU3V1eXUsWCRjKGuyyeuLQYfFpv6BAoIihFQryuYZsOWVvxUBvQOC0dOL2n on: branch: master test_script: diff --git a/src/NLog.Web/LayoutRenderers/AspNetApplicationValueLayoutRenderer.cs b/src/NLog.Web/LayoutRenderers/AspNetApplicationValueLayoutRenderer.cs index 95670bca..5cf5ae93 100644 --- a/src/NLog.Web/LayoutRenderers/AspNetApplicationValueLayoutRenderer.cs +++ b/src/NLog.Web/LayoutRenderers/AspNetApplicationValueLayoutRenderer.cs @@ -11,12 +11,12 @@ namespace NLog.Web.LayoutRenderers /// /// /// - /// ${aspnet-application:variable=myvariable} - produces "123" - /// ${aspnet-application:variable=anothervariable} - produces "01/01/2006 00:00:00" - /// ${aspnet-application:variable=anothervariable:culture=pl-PL} - produces "2006-01-01 00:00:00" - /// ${aspnet-application:variable=myvariable:padding=5} - produces " 123" - /// ${aspnet-application:variable=myvariable:padding=-5} - produces "123 " - /// ${aspnet-application:variable=stringvariable:upperCase=true} - produces "AAA BBB" + /// ${aspnet-application:item=myvariable} - produces "123" + /// ${aspnet-application:item=anothervariable} - produces "01/01/2006 00:00:00" + /// ${aspnet-application:item=anothervariable:culture=pl-PL} - produces "2006-01-01 00:00:00" + /// ${aspnet-application:item=myvariable:padding=5} - produces " 123" + /// ${aspnet-application:item=myvariable:padding=-5} - produces "123 " + /// ${aspnet-application:item=stringvariable:upperCase=true} - produces "AAA BBB" /// /// /// @@ -33,6 +33,8 @@ namespace NLog.Web.LayoutRenderers [LayoutRenderer("aspnet-application")] public class AspNetApplicationValueLayoutRenderer : AspNetLayoutRendererBase { + private readonly NLog.LayoutRenderers.Wrappers.ObjectPathRendererWrapper _objectPathRenderer = new NLog.LayoutRenderers.Wrappers.ObjectPathRendererWrapper(); + /// /// Gets or sets the item variable name. /// @@ -45,8 +47,14 @@ public class AspNetApplicationValueLayoutRenderer : AspNetLayoutRendererBase /// Gets or sets the variable name. /// /// + [Obsolete("Instead use Item. Marked obsolete with NLog.Web 5.3")] public string Variable { get => Item; set => Item = value; } + /// + /// Gets or sets the object-property-navigation-path for lookup of nested property + /// + public string ObjectPath { get => _objectPathRenderer.ObjectPath; set => _objectPathRenderer.ObjectPath = value; } + /// /// Format string for conversion from object to string. /// @@ -74,8 +82,23 @@ protected override void DoAppend(StringBuilder builder, LogEventInfo logEvent) return; } + var value = application[item]; + if (value is null) + { + return; + } + + if (!(ObjectPath is null)) + { + if (!_objectPathRenderer.TryGetPropertyValue(value, out value)) + return; + + if (value is null) + return; + } + var formatProvider = GetFormatProvider(logEvent, Culture); - builder.AppendFormattedValue(application[item], Format, formatProvider, ValueFormatter); + builder.AppendFormattedValue(value, Format, formatProvider, ValueFormatter); } } } \ No newline at end of file diff --git a/src/Shared/LayoutRenderers/AspNetItemValueLayoutRenderer.cs b/src/Shared/LayoutRenderers/AspNetItemValueLayoutRenderer.cs index eeb600b2..12ddf221 100644 --- a/src/Shared/LayoutRenderers/AspNetItemValueLayoutRenderer.cs +++ b/src/Shared/LayoutRenderers/AspNetItemValueLayoutRenderer.cs @@ -61,6 +61,7 @@ public class AspNetItemValueLayoutRenderer : AspNetLayoutRendererBase /// Gets or sets the item variable name. /// /// + [Obsolete("Instead use Item. Marked obsolete with NLog.Web 5.3")] public string Variable { get => Item; set => Item = value; } /// diff --git a/src/Shared/LayoutRenderers/AspNetSessionValueLayoutRenderer.cs b/src/Shared/LayoutRenderers/AspNetSessionValueLayoutRenderer.cs index 8bbbd077..2bef7236 100644 --- a/src/Shared/LayoutRenderers/AspNetSessionValueLayoutRenderer.cs +++ b/src/Shared/LayoutRenderers/AspNetSessionValueLayoutRenderer.cs @@ -56,6 +56,7 @@ public class AspNetSessionValueLayoutRenderer : AspNetLayoutRendererBase /// Gets or sets the session item name. /// /// + [Obsolete("Instead use Item. Marked obsolete with NLog.Web 5.3")] public string Variable { get => Item; set => Item = value; } /// diff --git a/tests/NLog.Web.Tests/LayoutRenderers/AspNetApplicationValueLayoutRendererTests.cs b/tests/NLog.Web.Tests/LayoutRenderers/AspNetApplicationValueLayoutRendererTests.cs index 02dc4d8a..bcf0f440 100644 --- a/tests/NLog.Web.Tests/LayoutRenderers/AspNetApplicationValueLayoutRendererTests.cs +++ b/tests/NLog.Web.Tests/LayoutRenderers/AspNetApplicationValueLayoutRendererTests.cs @@ -16,12 +16,12 @@ public class AspNetApplicationValueLayoutRendererTests : TestBase public void NullHttpContextRendersEmptyString() { var renderer = new AspNetApplicationValueLayoutRenderer(); - renderer.Variable = string.Empty; + renderer.Item = string.Empty; string result = renderer.Render(new LogEventInfo()); Assert.Empty(result); - renderer.Variable = null; + renderer.Item = null; result = renderer.Render(new LogEventInfo()); Assert.Empty(result); } @@ -32,7 +32,7 @@ public void VariableNotFoundRendersEmptyString() var httpContext = Substitute.For(); var renderer = new AspNetApplicationValueLayoutRenderer(); - renderer.Variable = "key"; + renderer.Item = "key"; renderer.HttpContextAccessor = new FakeHttpContextAccessor(httpContext); string result = renderer.Render(new LogEventInfo()); @@ -48,7 +48,7 @@ public void VariableFoundRendersValue(object expectedValue) var culture = CultureInfo.CurrentUICulture; var renderer = new AspNetApplicationValueLayoutRenderer(); - renderer.Variable = "key"; + renderer.Item = "key"; renderer.HttpContextAccessor = new FakeHttpContextAccessor(httpContext); renderer.Culture = culture; @@ -57,6 +57,24 @@ public void VariableFoundRendersValue(object expectedValue) Assert.Equal(Convert.ToString(expectedValue, culture), result); } + [Fact] + public void NestedObjectPath() + { + var expectedValue = "a"; + + var httpContext = Substitute.For(); + httpContext.Application["key"].Returns(Tuple.Create(expectedValue, 1)); + + var renderer = new AspNetApplicationValueLayoutRenderer(); + renderer.Item = "key"; + renderer.ObjectPath = "Item1"; + renderer.HttpContextAccessor = new FakeHttpContextAccessor(httpContext); + + string result = renderer.Render(new LogEventInfo()); + + Assert.Equal(expectedValue, result); + } + public static IEnumerable VariableFoundData { get diff --git a/tests/Shared/LayoutRenderers/AspNetItemValueLayoutRendererTests.cs b/tests/Shared/LayoutRenderers/AspNetItemValueLayoutRendererTests.cs index 3314ad78..4e92e196 100644 --- a/tests/Shared/LayoutRenderers/AspNetItemValueLayoutRendererTests.cs +++ b/tests/Shared/LayoutRenderers/AspNetItemValueLayoutRendererTests.cs @@ -40,7 +40,7 @@ public void VariableNotFoundRendersEmptyString() { // Arrange var (renderer, _) = CreateWithHttpContext(); - renderer.Variable = "key"; + renderer.Item = "key"; // Act string result = renderer.Render(new LogEventInfo()); @@ -64,7 +64,7 @@ public void CulturedVariableFoundRendersValue(object expectedValue) httpContext.Items["key"].Returns(expectedValue); #endif var cultureInfo = new CultureInfo("nl-NL"); - renderer.Variable = "key"; + renderer.Item = "key"; renderer.Culture = cultureInfo; // Act @@ -89,7 +89,7 @@ public void VariableFoundRendersValue(object expectedValue) httpContext.Items["key"].Returns(expectedValue); #endif var culture = CultureInfo.CurrentUICulture; - renderer.Variable = "key"; + renderer.Item = "key"; renderer.Culture = culture; // Act @@ -112,7 +112,7 @@ public void NestedPropertyRendersValueItem(string itemKey, string variable, obje httpContext.Items[itemKey].Returns(data); #endif var culture = CultureInfo.CurrentUICulture; - renderer.Variable = variable; + renderer.Item = variable; #pragma warning disable CS0618 // Type or member is obsolete renderer.EvaluateAsNestedProperties = true; #pragma warning restore CS0618 // Type or member is obsolete @@ -139,7 +139,7 @@ public void NestedPropertyRendersValueObjectPath(string itemKey, string variable httpContext.Items[itemKey].Returns(data); #endif var culture = CultureInfo.CurrentUICulture; - renderer.Variable = variable; + renderer.Item = variable; #pragma warning disable CS0618 // Type or member is obsolete renderer.EvaluateAsNestedProperties = true; #pragma warning restore CS0618 // Type or member is obsolete diff --git a/tests/Shared/LayoutRenderers/AspNetSessionValueLayoutRendererTests.cs b/tests/Shared/LayoutRenderers/AspNetSessionValueLayoutRendererTests.cs index 93b25515..c94132db 100644 --- a/tests/Shared/LayoutRenderers/AspNetSessionValueLayoutRendererTests.cs +++ b/tests/Shared/LayoutRenderers/AspNetSessionValueLayoutRendererTests.cs @@ -29,7 +29,7 @@ public void SimpleTest() { var appSettingLayoutRenderer = new AspNetSessionValueLayoutRenderer() { - Variable = "a" + Item = "a" }; ExecTest("a", "b", "b", appSettingLayoutRenderer); @@ -40,7 +40,7 @@ public void SimpleTest2() { var appSettingLayoutRenderer = new AspNetSessionValueLayoutRenderer() { - Variable = "a.b" + Item = "a.b" }; ExecTest("a.b", "c", "c", appSettingLayoutRenderer); @@ -51,7 +51,7 @@ public void NestedProps() { var appSettingLayoutRenderer = new AspNetSessionValueLayoutRenderer() { - Variable = "a.b", + Item = "a.b", #pragma warning disable CS0618 // Type or member is obsolete EvaluateAsNestedProperties = true #pragma warning restore CS0618 // Type or member is obsolete @@ -67,7 +67,7 @@ public void NestedPropsObjectPath() { var appSettingLayoutRenderer = new AspNetSessionValueLayoutRenderer() { - Variable = "a", + Item = "a", ObjectPath = "b", }; @@ -81,7 +81,7 @@ public void NestedProps2() { var appSettingLayoutRenderer = new AspNetSessionValueLayoutRenderer() { - Variable = "a.b.c", + Item = "a.b.c", #pragma warning disable CS0618 // Type or member is obsolete EvaluateAsNestedProperties = true #pragma warning restore CS0618 // Type or member is obsolete @@ -97,7 +97,7 @@ public void NestedPropsObjectPath2() { var appSettingLayoutRenderer = new AspNetSessionValueLayoutRenderer() { - Variable = "a", + Item = "a", ObjectPath = "b.c" }; @@ -111,7 +111,7 @@ public void NestedProps3() { var appSettingLayoutRenderer = new AspNetSessionValueLayoutRenderer() { - Variable = "a.b..c", + Item = "a.b..c", #pragma warning disable CS0618 // Type or member is obsolete EvaluateAsNestedProperties = true #pragma warning restore CS0618 // Type or member is obsolete @@ -127,7 +127,7 @@ public void EmptyPath() { var appSettingLayoutRenderer = new AspNetSessionValueLayoutRenderer() { - Variable = "", + Item = "", #pragma warning disable CS0618 // Type or member is obsolete EvaluateAsNestedProperties = true #pragma warning restore CS0618 // Type or member is obsolete @@ -143,7 +143,7 @@ public void EmptyVarname() { var appSettingLayoutRenderer = new AspNetSessionValueLayoutRenderer() { - Variable = "", + Item = "", #pragma warning disable CS0618 // Type or member is obsolete EvaluateAsNestedProperties = true #pragma warning restore CS0618 // Type or member is obsolete @@ -201,6 +201,6 @@ private void ExecTest(string key, object value, object expected, AspNetLayoutRen Assert.Equal(expected, rendered); } - } } +} #endif \ No newline at end of file diff --git a/tests/Shared/LayoutRenderers/AspNetSessionValueLayoutRendererTests2.cs b/tests/Shared/LayoutRenderers/AspNetSessionValueLayoutRendererTests2.cs index f0b59ff8..0246b316 100644 --- a/tests/Shared/LayoutRenderers/AspNetSessionValueLayoutRendererTests2.cs +++ b/tests/Shared/LayoutRenderers/AspNetSessionValueLayoutRendererTests2.cs @@ -45,7 +45,7 @@ public void SingleStringItemRendersCorrectValue() { // Arrange var (renderer, _) = CreateRenderer(); - renderer.Variable = "a"; + renderer.Item = "a"; // Act string result = renderer.Render(LogEventInfo.CreateNullEvent()); @@ -59,7 +59,7 @@ public void SingleIntItemRendersCorrectValue() { // Arrange var (renderer, _) = CreateRenderer(); - renderer.Variable = "b"; + renderer.Item = "b"; renderer.ValueType = SessionValueType.Int32; // Act @@ -74,7 +74,7 @@ public void MissingItemRendersEmpty() { // Arrange var (renderer, _) = CreateRenderer(); - renderer.Variable = "nope"; + renderer.Item = "nope"; // Act string result = renderer.Render(LogEventInfo.CreateNullEvent()); @@ -98,7 +98,7 @@ private static (AspNetSessionValueLayoutRenderer, HttpContext) CreateRenderer(bo private class SessionFeatureMock : ISessionFeature { - #region Implementation of ISessionFeature +#region Implementation of ISessionFeature /// public SessionFeatureMock(ISession session) @@ -109,7 +109,7 @@ public SessionFeatureMock(ISession session) /// public ISession Session { get; set; } - #endregion +#endregion } private class SessionMock : ISession @@ -123,7 +123,7 @@ public SessionMock(bool throwsErrorOnGet) _throwsErrorOnGet = throwsErrorOnGet; } - #region Implementation of ISession +#region Implementation of ISession /// /// Load the session from the data store. This may throw if the data store is unavailable. @@ -193,7 +193,7 @@ public void Clear() /// public IEnumerable Keys => _values.Keys; - #endregion +#endregion } } }