diff --git a/CHANGELOG.MD b/CHANGELOG.MD
index ed202bc3..782d88b6 100644
--- a/CHANGELOG.MD
+++ b/CHANGELOG.MD
@@ -4,6 +4,24 @@ See also [releases](https://github.com/NLog/NLog.Web/releases) and [milestones](
Date format: (year/month/day)
+### Version 5.2.0 (2022/11/27)
+
+- **NLog.Web.AspNetCore**
+ - [#885](https://github.com/NLog/NLog.Web/pull/885) Changed LoadConfigurationFromAppSettings to prioritize current directory (#885) (@snakefoot)
+ - [#887](https://github.com/NLog/NLog.Web/pull/887) Changed AspNetAppBasePathLayoutRenderer to prioritize current directory (#887) (@snakefoot)
+ - [#890](https://github.com/NLog/NLog.Web/pull/890) Add ObjectPath to AspNetItemValueLayoutRenderer as better alternative to EvaluateAsNestedProperties (#890) (@bakgerman)
+ - [#889](https://github.com/NLog/NLog.Web/pull/889) Use CallerArgumentExpressionAttribute in helper method for throwing ArgumentNullException (#889) (@bakgerman)
+ - [#894](https://github.com/NLog/NLog.Web/pull/894) Use AspNetSessionValueLayoutRenderer in helper method for throwing ArgumentNullException (#894) (@snakefoot)
+ - [#891](https://github.com/NLog/NLog.Web/pull/891) Skip allocating RouteData when only need to lookup single value (#891) (@snakefoot)
+ - [#878](https://github.com/NLog/NLog.Web/pull/878) + [#879](https://github.com/NLog/NLog.Web/pull/879) Use RegisterConfigSettings instead of ConfigSettingLayoutRenderer (#878 + #879) (@snakefoot)
+ - [#894](https://github.com/NLog/NLog.Web/pull/894) Updated dependency NLog.Extensions.Logging v5.2.0 (#894) (@snakefoot)
+
+- **NLog.Web**
+ - [#890](https://github.com/NLog/NLog.Web/pull/890) Add ObjectPath to AspNetItemValueLayoutRenderer as better alternative to EvaluateAsNestedProperties (#890) (@bakgerman)
+ - [#894](https://github.com/NLog/NLog.Web/pull/894) Use AspNetSessionValueLayoutRenderer in helper method for throwing ArgumentNullException (#894) (@snakefoot)
+ - [#889](https://github.com/NLog/NLog.Web/pull/889) Use CallerArgumentExpressionAttribute in helper method for throwing ArgumentNullException (#889) (@bakgerman)
+ - [#894](https://github.com/NLog/NLog.Web/pull/894) Updated dependency NLog v5.1.0 (#894) (@snakefoot)
+
### Version 5.1.5 (2022/10/26)
- **NLog.Web.AspNetCore**
diff --git a/appveyor.yml b/appveyor.yml
index 7dae29f5..81230eb6 100644
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -1,4 +1,4 @@
-version: 5.1.0.{build}
+version: 5.2.0.{build}
clone_folder: c:\projects\nlogweb
configuration: Release
image: Visual Studio 2022
diff --git a/build.ps1 b/build.ps1
index e076fe50..8cd736bd 100644
--- a/build.ps1
+++ b/build.ps1
@@ -2,7 +2,7 @@
# creates NuGet package at \artifacts
dotnet --version
-$versionPrefix = "5.1.5" # Also update version for minor versions in appveyor.yml
+$versionPrefix = "5.2.0" # Also update version for minor versions in appveyor.yml
$versionSuffix = ""
$versionFile = $versionPrefix + "." + ${env:APPVEYOR_BUILD_NUMBER}
if ($env:APPVEYOR_PULL_REQUEST_NUMBER) {
diff --git a/examples/ASP.NET 4.6.1/Visual Studio 2017/ASP.NET 4.6.1 - VS2017/packages.config b/examples/ASP.NET 4.6.1/Visual Studio 2017/ASP.NET 4.6.1 - VS2017/packages.config
index 47dec917..aeba3130 100644
--- a/examples/ASP.NET 4.6.1/Visual Studio 2017/ASP.NET 4.6.1 - VS2017/packages.config
+++ b/examples/ASP.NET 4.6.1/Visual Studio 2017/ASP.NET 4.6.1 - VS2017/packages.config
@@ -12,7 +12,7 @@
-
+
\ No newline at end of file
diff --git a/src/NLog.Web.AspNetCore/NLog.Web.AspNetCore.csproj b/src/NLog.Web.AspNetCore/NLog.Web.AspNetCore.csproj
index d861addd..b607dcd0 100644
--- a/src/NLog.Web.AspNetCore/NLog.Web.AspNetCore.csproj
+++ b/src/NLog.Web.AspNetCore/NLog.Web.AspNetCore.csproj
@@ -21,8 +21,14 @@ Supported platforms:
NLog.Web.AspNetCore
logging;log;NLog;web;aspnet;aspnetcore;MVC;Microsoft.Extensions.Logging;httpcontext
-- Introduced Introduced NET6 since LTS (@snakefoot)
-- Updated NLog.Extensions.Logging to v5.1.0 (@snakefoot)
+- Changed LoadConfigurationFromAppSettings to prioritize current directory (#885) (@snakefoot)
+- Changed AspNetAppBasePathLayoutRenderer to prioritize current directory (#887) (@snakefoot)
+- Add ObjectPath to AspNetItemValueLayoutRenderer as better alternative to EvaluateAsNestedProperties (#890) (@bakgerman)
+- Add ObjectPath to AspNetSessionValueLayoutRenderer as better alternative to EvaluateAsNestedProperties (#894) (@snakefoot)
+- Use CallerArgumentExpressionAttribute in helper method for throwing ArgumentNullException (#889) (@bakgerman)
+- Skip allocating RouteData when only need to lookup single value (#891) (@snakefoot)
+- Use RegisterConfigSettings instead of ConfigSettingLayoutRenderer (#878 + #879) (@snakefoot)
+- Updated dependency NLog.Extensions.Logging v5.2.0 (#894) (@snakefoot)
List of major changes in NLog 5.0: https://nlog-project.org/2022/05/16/nlog-5-0-finally-ready.html
@@ -75,7 +81,7 @@ List of available Layout Renderers: https://nlog-project.org/config/?tab=layout-
$(DefineConstants);ASP_NET_CORE;ASP_NET_CORE3
-
+
diff --git a/src/NLog.Web/NLog.Web.csproj b/src/NLog.Web/NLog.Web.csproj
index 1298aa1f..96e33c5c 100644
--- a/src/NLog.Web/NLog.Web.csproj
+++ b/src/NLog.Web/NLog.Web.csproj
@@ -51,7 +51,7 @@ List of available Layout Renderers: https://nlog-project.org/config/?tab=layout-
-
+
diff --git a/src/Shared/Internal/PropertyReader.cs b/src/Shared/Internal/PropertyReader.cs
index 0d612d51..caa9a6af 100644
--- a/src/Shared/Internal/PropertyReader.cs
+++ b/src/Shared/Internal/PropertyReader.cs
@@ -4,6 +4,7 @@
namespace NLog.Web.Internal
{
+ [Obsolete("Instead use ObjectPath. Marked obsolete with NLog.Web 5.2")]
internal static class PropertyReader
{
///
@@ -14,6 +15,7 @@ internal static class PropertyReader
/// function to get a value with this key
/// evaluate as a nested property path. E.g. A.B is property B inside A.
/// value
+ [Obsolete("Instead use ObjectPath. Marked obsolete with NLog.Web 5.2")]
public static object GetValue(string key, T container, Func getVal, bool evaluateAsNestedProperties)
{
if (string.IsNullOrEmpty(key))
@@ -24,30 +26,7 @@ public static object GetValue(string key, T container, Func
- /// Get value of a property
- ///
- /// key
- /// Container to perform value lookup using key
- /// function to get a value with this key
- /// evaluate the string as a dot notated path to a aproperty in the object, returned by lookup by the key parameter
- /// value
- public static object GetValue(string key, T container, Func getVal, string objectPath)
- {
- if (string.IsNullOrEmpty(key))
- {
- return null;
- }
-
- var value = getVal(container, key);
- if (value == null)
- {
- return null;
- }
-
- return GetValueAsNestedProperties(value, objectPath);
- }
-
+ [Obsolete("Instead use ObjectPath. Marked obsolete with NLog.Web 5.2")]
private static object GetValueAsNestedProperties(string key, T container, Func getVal)
{
var path = key.Contains('.') ? key.Split(new[] { '.' }, StringSplitOptions.RemoveEmptyEntries) : null;
@@ -69,26 +48,7 @@ private static object GetValueAsNestedProperties(string key, T container, Fun
return value;
}
- private static object GetValueAsNestedProperties(object value, string objectPath)
- {
- var path = objectPath.Split(new[] { '.' }, StringSplitOptions.RemoveEmptyEntries);
-
- if (value != null && path?.Length > 0)
- {
- for (int i = 0; i < path.Length; ++i)
- {
- var propertyInfo = GetPropertyInfo(value, path[i]);
- value = propertyInfo?.GetValue(value, null);
- if (value == null)
- {
- break;
- }
- }
- }
-
- return value;
- }
-
+ [Obsolete("Instead use ObjectPath. Marked obsolete with NLog.Web 5.2")]
private static PropertyInfo GetPropertyInfo(object value, string propertyName)
{
#if !ASP_NET_CORE
diff --git a/src/Shared/LayoutRenderers/AspNetItemValueLayoutRenderer.cs b/src/Shared/LayoutRenderers/AspNetItemValueLayoutRenderer.cs
index d360f3c6..eeb600b2 100644
--- a/src/Shared/LayoutRenderers/AspNetItemValueLayoutRenderer.cs
+++ b/src/Shared/LayoutRenderers/AspNetItemValueLayoutRenderer.cs
@@ -36,6 +36,8 @@ namespace NLog.Web.LayoutRenderers
[LayoutRenderer("aspnet-item")]
public class AspNetItemValueLayoutRenderer : AspNetLayoutRendererBase
{
+ private readonly NLog.LayoutRenderers.Wrappers.ObjectPathRendererWrapper _objectPathRenderer = new NLog.LayoutRenderers.Wrappers.ObjectPathRendererWrapper();
+
///
/// Gets or sets the item variable name.
///
@@ -53,7 +55,7 @@ public class AspNetItemValueLayoutRenderer : AspNetLayoutRendererBase
/// This will emit the First Name property of the object in HttpContext.Items woith the key of 'person' in the collection
///
///
- public string ObjectPath { get; set; }
+ public string ObjectPath { get => _objectPathRenderer.ObjectPath; set => _objectPathRenderer.ObjectPath = value; }
///
/// Gets or sets the item variable name.
@@ -67,6 +69,7 @@ public class AspNetItemValueLayoutRenderer : AspNetLayoutRendererBase
/// invoked since ObjectPath is set
///
///
+ [Obsolete("Instead use ObjectPath. Marked obsolete with NLog.Web 5.2")]
public bool EvaluateAsNestedProperties { get; set; }
///
@@ -84,24 +87,36 @@ public class AspNetItemValueLayoutRenderer : AspNetLayoutRendererBase
///
protected override void DoAppend(StringBuilder builder, LogEventInfo logEvent)
{
- var context = HttpContextAccessor.HttpContext;
+ var item = Item;
+ if (string.IsNullOrEmpty(item))
+ {
+ return;
+ }
- if (Item == null)
+ var context = HttpContextAccessor.HttpContext;
+ if (context is null)
{
return;
}
object value = null;
- // Function using the Item string as the object path
- if (ObjectPath == null)
+ if (ObjectPath is null)
{
- value = PropertyReader.GetValue(Item, context?.Items, (items, key) => LookupItemValue(items, key), EvaluateAsNestedProperties);
+#pragma warning disable CS0618 // Type or member is obsolete
+ value = PropertyReader.GetValue(item, context?.Items, (items, key) => LookupItemValue(items, key), EvaluateAsNestedProperties);
+#pragma warning restore CS0618 // Type or member is obsolete
+ if (value is null)
+ return;
}
- // Function using the ObjectPath as the object path, hard code evaluateNestedProperties argument to true
else
{
- value = PropertyReader.GetValue(Item, context?.Items, (items, key) => LookupItemValue(items, key), ObjectPath);
+ value = LookupItemValue(context?.Items, item);
+ if (value is null)
+ return;
+
+ if (!_objectPathRenderer.TryGetPropertyValue(value, out value))
+ return;
}
var formatProvider = GetFormatProvider(logEvent, Culture);
diff --git a/src/Shared/LayoutRenderers/AspNetSessionValueLayoutRenderer.cs b/src/Shared/LayoutRenderers/AspNetSessionValueLayoutRenderer.cs
index 4ba9f59d..8bbbd077 100644
--- a/src/Shared/LayoutRenderers/AspNetSessionValueLayoutRenderer.cs
+++ b/src/Shared/LayoutRenderers/AspNetSessionValueLayoutRenderer.cs
@@ -42,6 +42,8 @@ namespace NLog.Web.LayoutRenderers
[LayoutRenderer("aspnet-session")]
public class AspNetSessionValueLayoutRenderer : AspNetLayoutRendererBase
{
+ private readonly NLog.LayoutRenderers.Wrappers.ObjectPathRendererWrapper _objectPathRenderer = new NLog.LayoutRenderers.Wrappers.ObjectPathRendererWrapper();
+
///
/// Gets or sets the session item name.
///
@@ -56,10 +58,16 @@ public class AspNetSessionValueLayoutRenderer : AspNetLayoutRendererBase
///
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; }
+
///
/// Gets or sets whether variables with a dot are evaluated as properties or not
///
///
+ [Obsolete("Instead use ObjectPath. Marked obsolete with NLog.Web 5.2")]
public bool EvaluateAsNestedProperties { get; set; }
///
@@ -99,13 +107,13 @@ public SessionValueType ValueType
protected override void DoAppend(StringBuilder builder, LogEventInfo logEvent)
{
var item = Item;
- if (item == null)
+ if (string.IsNullOrEmpty(item))
{
return;
}
var context = HttpContextAccessor.HttpContext;
- if (context == null)
+ if (context is null)
{
return;
}
@@ -131,12 +139,28 @@ protected override void DoAppend(StringBuilder builder, LogEventInfo logEvent)
return;
}
- var value = PropertyReader.GetValue(item, contextSession, _sessionValueLookup, EvaluateAsNestedProperties);
- if (value != null)
+ object value = null;
+
+ if (ObjectPath is null)
{
- var formatProvider = GetFormatProvider(logEvent, Culture);
- builder.AppendFormattedValue(value, Format, formatProvider, ValueFormatter);
+#pragma warning disable CS0618 // Type or member is obsolete
+ value = PropertyReader.GetValue(item, contextSession, _sessionValueLookup, EvaluateAsNestedProperties);
+#pragma warning restore CS0618 // Type or member is obsolete
+ if (value is null)
+ return;
}
+ else
+ {
+ value = _sessionValueLookup(contextSession, item);
+ if (value is null)
+ return;
+
+ if (!_objectPathRenderer.TryGetPropertyValue(value, out value))
+ return;
+ }
+
+ var formatProvider = GetFormatProvider(logEvent, Culture);
+ builder.AppendFormattedValue(value, Format, formatProvider, ValueFormatter);
}
}
diff --git a/tests/Shared/LayoutRenderers/AspNetItemValueLayoutRendererTests.cs b/tests/Shared/LayoutRenderers/AspNetItemValueLayoutRendererTests.cs
index 4cf62ccd..3314ad78 100644
--- a/tests/Shared/LayoutRenderers/AspNetItemValueLayoutRendererTests.cs
+++ b/tests/Shared/LayoutRenderers/AspNetItemValueLayoutRendererTests.cs
@@ -113,7 +113,9 @@ public void NestedPropertyRendersValueItem(string itemKey, string variable, obje
#endif
var culture = CultureInfo.CurrentUICulture;
renderer.Variable = variable;
+#pragma warning disable CS0618 // Type or member is obsolete
renderer.EvaluateAsNestedProperties = true;
+#pragma warning restore CS0618 // Type or member is obsolete
renderer.Culture = culture;
// Act
@@ -138,7 +140,9 @@ public void NestedPropertyRendersValueObjectPath(string itemKey, string variable
#endif
var culture = CultureInfo.CurrentUICulture;
renderer.Variable = variable;
+#pragma warning disable CS0618 // Type or member is obsolete
renderer.EvaluateAsNestedProperties = true;
+#pragma warning restore CS0618 // Type or member is obsolete
renderer.Culture = culture;
// Act
@@ -209,7 +213,9 @@ public void NestedItemRendersProperly()
#endif
renderer.Item = "person.Name.First";
+#pragma warning disable CS0618 // Type or member is obsolete
renderer.EvaluateAsNestedProperties = true;
+#pragma warning restore CS0618 // Type or member is obsolete
// Act
string result = renderer.Render(new LogEventInfo());
@@ -247,7 +253,9 @@ public void NestedObjectPathRendersProperly()
renderer.Item = "person";
renderer.ObjectPath = "Name.Last";
+#pragma warning disable CS0618 // Type or member is obsolete
renderer.EvaluateAsNestedProperties = false;
+#pragma warning restore CS0618 // Type or member is obsolete
// Act
string result = renderer.Render(new LogEventInfo());
@@ -284,8 +292,6 @@ public void NestedObjectPathRendersProperlyII()
renderer.Item = "person";
renderer.ObjectPath = "Name.Last";
- renderer.EvaluateAsNestedProperties = false;
-
// Act
string result = renderer.Render(new LogEventInfo());
diff --git a/tests/Shared/LayoutRenderers/AspNetSessionValueLayoutRendererTests.cs b/tests/Shared/LayoutRenderers/AspNetSessionValueLayoutRendererTests.cs
index d3c5abaf..93b25515 100644
--- a/tests/Shared/LayoutRenderers/AspNetSessionValueLayoutRendererTests.cs
+++ b/tests/Shared/LayoutRenderers/AspNetSessionValueLayoutRendererTests.cs
@@ -52,7 +52,23 @@ public void NestedProps()
var appSettingLayoutRenderer = new AspNetSessionValueLayoutRenderer()
{
Variable = "a.b",
+#pragma warning disable CS0618 // Type or member is obsolete
EvaluateAsNestedProperties = true
+#pragma warning restore CS0618 // Type or member is obsolete
+ };
+
+ var o = new { b = "c" };
+ //set in "a"
+ ExecTest("a", o, "c", appSettingLayoutRenderer);
+ }
+
+ [Fact]
+ public void NestedPropsObjectPath()
+ {
+ var appSettingLayoutRenderer = new AspNetSessionValueLayoutRenderer()
+ {
+ Variable = "a",
+ ObjectPath = "b",
};
var o = new { b = "c" };
@@ -66,7 +82,23 @@ public void NestedProps2()
var appSettingLayoutRenderer = new AspNetSessionValueLayoutRenderer()
{
Variable = "a.b.c",
+#pragma warning disable CS0618 // Type or member is obsolete
EvaluateAsNestedProperties = true
+#pragma warning restore CS0618 // Type or member is obsolete
+ };
+
+ var o = new { b = "c" };
+ //set in "a"
+ ExecTest("a", o, "", appSettingLayoutRenderer);
+ }
+
+ [Fact]
+ public void NestedPropsObjectPath2()
+ {
+ var appSettingLayoutRenderer = new AspNetSessionValueLayoutRenderer()
+ {
+ Variable = "a",
+ ObjectPath = "b.c"
};
var o = new { b = "c" };
@@ -80,7 +112,9 @@ public void NestedProps3()
var appSettingLayoutRenderer = new AspNetSessionValueLayoutRenderer()
{
Variable = "a.b..c",
+#pragma warning disable CS0618 // Type or member is obsolete
EvaluateAsNestedProperties = true
+#pragma warning restore CS0618 // Type or member is obsolete
};
var o = new { b = "c" };
@@ -94,7 +128,9 @@ public void EmptyPath()
var appSettingLayoutRenderer = new AspNetSessionValueLayoutRenderer()
{
Variable = "",
+#pragma warning disable CS0618 // Type or member is obsolete
EvaluateAsNestedProperties = true
+#pragma warning restore CS0618 // Type or member is obsolete
};
var o = new { b = "c" };
@@ -108,7 +144,9 @@ public void EmptyVarname()
var appSettingLayoutRenderer = new AspNetSessionValueLayoutRenderer()
{
Variable = "",
- EvaluateAsNestedProperties = false
+#pragma warning disable CS0618 // Type or member is obsolete
+ EvaluateAsNestedProperties = true
+#pragma warning restore CS0618 // Type or member is obsolete
};
var o = new { b = "c" };