-
Notifications
You must be signed in to change notification settings - Fork 165
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Added Layout renderer for ASP.NET Request route parameters (#740)
* Added Layout renderer for ASP.NET Request route parameters * Added unit tests of AspNetRequestRouteParametersRenderer
- Loading branch information
1 parent
0294fd7
commit ecac594
Showing
2 changed files
with
167 additions
and
0 deletions.
There are no files selected for viewing
87 changes: 87 additions & 0 deletions
87
src/Shared/LayoutRenderers/AspNetRequestRouteParametersRenderer.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
using System.Text; | ||
using NLog.LayoutRenderers; | ||
using System.Collections.Generic; | ||
using System.Linq; | ||
#if !ASP_NET_CORE | ||
using System.Web.Routing; | ||
#else | ||
using Microsoft.AspNetCore.Routing; | ||
#endif | ||
|
||
namespace NLog.Web.LayoutRenderers | ||
{ | ||
/// <summary> | ||
/// ASP.NET Request Route Parameters | ||
/// </summary> | ||
/// <example> | ||
/// <para>Example usage of ${aspnet-request-routeparameters}:</para> | ||
/// <code lang="NLog Layout Renderer"> | ||
/// ${aspnet-request-routeparameters:OutputFormat=Flat} | ||
/// ${aspnet-request-routeparameters:OutputFormat=JsonArray} | ||
/// ${aspnet-request-routeparameters:OutputFormat=JsonDictionary} | ||
/// </code> | ||
/// </example> | ||
[LayoutRenderer("aspnet-request-routeparameters")] | ||
public class AspNetRequestRouteParametersRenderer : AspNetLayoutMultiValueRendererBase | ||
{ | ||
/// <summary> | ||
/// List Route Parameter' Key to be rendered from Request. | ||
/// If empty, then render all parameters | ||
/// </summary> | ||
public List<string> RouteParameterKeys { get; set; } | ||
|
||
/// <summary> | ||
/// Renders the specified ASP.NET Route Parameters and appends it to the specified <see cref="StringBuilder" />. | ||
/// </summary> | ||
/// <param name="builder"></param> | ||
/// <param name="logEvent"></param> | ||
protected override void DoAppend(StringBuilder builder, LogEventInfo logEvent) | ||
{ | ||
var context = HttpContextAccessor.HttpContext; | ||
if (context == null) | ||
{ | ||
return; | ||
} | ||
|
||
#if !ASP_NET_CORE | ||
RouteValueDictionary routeParameters = RouteTable.Routes?.GetRouteData(context)?.Values; | ||
#else | ||
RouteValueDictionary routeParameters = context.GetRouteData()?.Values; | ||
#endif | ||
|
||
bool printAllRouteParameter = RouteParameterKeys == null || RouteParameterKeys.Count == 0; | ||
List<string> routeParameterKeys = RouteParameterKeys; | ||
if (routeParameters == null || routeParameters.Count == 0) | ||
{ | ||
return; | ||
} | ||
|
||
if (printAllRouteParameter) | ||
{ | ||
routeParameterKeys = routeParameters.Keys.ToList(); | ||
} | ||
|
||
IEnumerable<KeyValuePair<string, string>> pairs = GetPairs(routeParameters, routeParameterKeys); | ||
SerializePairs(pairs, builder, logEvent); | ||
} | ||
|
||
private static IEnumerable<KeyValuePair<string, string>> GetPairs(RouteValueDictionary routeParameters, List<string> routeParameterKeys) | ||
{ | ||
foreach (string key in routeParameterKeys) | ||
{ | ||
// This platform specific code is to prevent an unncessary .ToString call otherwise. | ||
|
||
if (!routeParameters.TryGetValue(key, out object objValue)) | ||
{ | ||
continue; | ||
} | ||
|
||
string value = objValue.ToString(); | ||
if (!string.IsNullOrEmpty(value)) | ||
{ | ||
yield return new KeyValuePair<string, string>(key, value); | ||
} | ||
} | ||
} | ||
} | ||
} |
80 changes: 80 additions & 0 deletions
80
tests/Shared/LayoutRenderers/AspNetRequestRouteParametersRendererTests.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using NLog.Web.LayoutRenderers; | ||
using NLog.Web.Enums; | ||
using Xunit; | ||
using System.Collections.Specialized; | ||
using NSubstitute; | ||
#if ASP_NET_CORE | ||
using Microsoft.AspNetCore.Http; | ||
using Microsoft.AspNetCore.Http.Features; | ||
using Microsoft.AspNetCore.Routing; | ||
#endif | ||
|
||
namespace NLog.Web.Tests.LayoutRenderers | ||
{ | ||
public class AspNetRequestRouteParametersRendererTests : LayoutRenderersTestBase<AspNetRequestRouteParametersRenderer> | ||
{ | ||
[Fact] | ||
public void NullRouteParametersRenderersEmptyString() | ||
{ | ||
// Arrange | ||
var (renderer, httpContext) = CreateWithHttpContext(); | ||
|
||
AddRoutingFeature(httpContext); | ||
|
||
// Act | ||
string result = renderer.Render(LogEventInfo.CreateNullEvent()); | ||
|
||
// Assert | ||
Assert.Empty(result); | ||
} | ||
|
||
#if ASP_NET_CORE | ||
[Fact] | ||
public void NullKeyRendersAllRouteParameters() | ||
{ | ||
// Arrange | ||
var (renderer, httpContext) = CreateWithHttpContext(); | ||
renderer.RouteParameterKeys = null; | ||
|
||
SetupRouteParameters(httpContext); | ||
|
||
// Act | ||
string result = renderer.Render(LogEventInfo.CreateNullEvent()); | ||
|
||
// Assert | ||
Assert.Equal("key1=value1,key2=value2", result); | ||
} | ||
|
||
[Fact] | ||
public void SingleKeyRendersRouteParameter() | ||
{ | ||
// Arrange | ||
var (renderer, httpContext) = CreateWithHttpContext(); | ||
renderer.RouteParameterKeys = new List<string> { "key2" }; | ||
|
||
SetupRouteParameters(httpContext); | ||
|
||
// Act | ||
string result = renderer.Render(LogEventInfo.CreateNullEvent()); | ||
|
||
// Assert | ||
Assert.Equal("key2=value2", result); | ||
} | ||
|
||
private void SetupRouteParameters(HttpContext httpContext) | ||
{ | ||
var routeData = new RouteData(); | ||
var routingFeature = Substitute.For<IRoutingFeature>(); | ||
var collection = new FeatureCollection(); | ||
collection.Set(routingFeature); | ||
httpContext.Features.Returns(collection); | ||
|
||
routeData.Values.Add("key1", "value1"); | ||
routeData.Values.Add("key2", "value2"); | ||
routingFeature.RouteData.Returns(routeData); | ||
} | ||
#endif | ||
} | ||
} |