diff --git a/src/Shared/LayoutRenderers/AspNetResponseStatusCodeRenderer.cs b/src/Shared/LayoutRenderers/AspNetResponseStatusCodeRenderer.cs
index d5efa23e..e2e75b4d 100644
--- a/src/Shared/LayoutRenderers/AspNetResponseStatusCodeRenderer.cs
+++ b/src/Shared/LayoutRenderers/AspNetResponseStatusCodeRenderer.cs
@@ -1,4 +1,6 @@
-using System.Text;
+using System;
+using System.Net;
+using System.Text;
using NLog.Config;
using NLog.LayoutRenderers;
using NLog.Web.Internal;
@@ -9,12 +11,31 @@ namespace NLog.Web.LayoutRenderers
/// ASP.NET Response Status Code.
///
///
- /// ${aspnet-response-statuscode}
+ /// ${aspnet-response-statuscode} emits the http status code as integer
+ /// ${aspnet-response-statuscode:Format=D} emits the http status code as integer
+ /// ${aspnet-response-statuscode:Format=F} emits the http status code as enum-string-value
+ /// ${aspnet-response-statuscode:Format=G} emits the http status code as enum-string-value
+ /// ${aspnet-response-statuscode:Format=X} emits the http status code as hexadecimal
///
/// Documentation on NLog Wiki
[LayoutRenderer("aspnet-response-statuscode")]
public class AspNetResponseStatusCodeRenderer : AspNetLayoutRendererBase
{
+ ///
+ /// A valid enumeration format string, defaults to integer format
+ ///
+ ///
+ /// Supported Values, Case Insensitive
+ /// D: outputs the HttpStatusCode enum as a integer
+ /// F: outputs the HttpStatusCode enum as a string if possible, otherwise an integer
+ /// G: outputs the HttpStatusCode enum as a string if possible, otherwise an integer
+ /// X: outputs the HttpStatusCode enum as a hexadecimal
+ ///
+ /// Documentation on Enum Format Strings
+
+ [DefaultParameter]
+ public string Format { get; set; } = "d";
+
///
protected override void DoAppend(StringBuilder builder, LogEventInfo logEvent)
{
@@ -24,11 +45,22 @@ protected override void DoAppend(StringBuilder builder, LogEventInfo logEvent)
return;
}
- int statusCode = httpResponse.StatusCode;
+ var statusCode = httpResponse.StatusCode;
+ if (statusCode < 100 || statusCode > 599)
+ {
+ // Only output valid HTTP status codes
+ return;
+ }
- if (statusCode >= 100 && statusCode <= 599)
+ try
+ {
+ builder.Append(((HttpStatusCode)statusCode).ToString(Format));
+ }
+ catch (Exception ex)
{
- builder.Append(statusCode);
+ NLog.Common.InternalLogger.Error(ex,
+ "Error occurred outputting HttpStatusCode enum ToString() with format specifier of {0} and value of {1}",
+ Format, statusCode);
}
}
}
diff --git a/tests/Shared/LayoutRenderers/AspNetResponseStatusCodeRendererTests.cs b/tests/Shared/LayoutRenderers/AspNetResponseStatusCodeRendererTests.cs
index 9d6e0360..3a7463a9 100644
--- a/tests/Shared/LayoutRenderers/AspNetResponseStatusCodeRendererTests.cs
+++ b/tests/Shared/LayoutRenderers/AspNetResponseStatusCodeRendererTests.cs
@@ -1,4 +1,5 @@
-using NLog.Web.LayoutRenderers;
+using System.Net;
+using NLog.Web.LayoutRenderers;
using NSubstitute;
using Xunit;
@@ -7,7 +8,7 @@ namespace NLog.Web.Tests.LayoutRenderers
public class AspNetResponseStatusCodeRendererTests : LayoutRenderersTestBase
{
[Fact]
- public void StatusCode_Set_Renderer()
+ public void StatusCode_Set_Renderer_DefaultFormat()
{
// Arrange
var (renderer, httpContext) = CreateWithHttpContext();
@@ -20,13 +21,109 @@ public void StatusCode_Set_Renderer()
Assert.Equal("200", result);
}
+ [Fact]
+ public void StatusCode_Set_Renderer_EnumFormatF()
+ {
+ // Arrange
+ var (renderer, httpContext) = CreateWithHttpContext();
+ renderer.Format = "f";
+
+ httpContext.Response.StatusCode.Returns(200);
+
+ // Act
+ string result = renderer.Render(new LogEventInfo());
+
+ // Assert
+ Assert.Equal(((HttpStatusCode)200).ToString(), result);
+ }
+
+ [Fact]
+ public void StatusCode_Set_Renderer_EnumFormatG()
+ {
+ // Arrange
+ var (renderer, httpContext) = CreateWithHttpContext();
+ renderer.Format = "g";
+
+ httpContext.Response.StatusCode.Returns(200);
+
+ // Act
+ string result = renderer.Render(new LogEventInfo());
+
+ // Assert
+ Assert.Equal(((HttpStatusCode)200).ToString(), result);
+ }
+
+ [Fact]
+ public void StatusCode_Set_Renderer_IntegerFormat()
+ {
+ // Arrange
+ var (renderer, httpContext) = CreateWithHttpContext();
+ renderer.Format = "d";
+
+ httpContext.Response.StatusCode.Returns(200);
+
+ // Act
+ string result = renderer.Render(new LogEventInfo());
+
+ // Assert
+ Assert.Equal("200", result);
+ }
+
+ [Fact]
+ public void StatusCode_Set_Renderer_HexFormat()
+ {
+ // Arrange
+ var (renderer, httpContext) = CreateWithHttpContext();
+ renderer.Format = "x";
+
+ httpContext.Response.StatusCode.Returns(200);
+
+ // Act
+ string result = renderer.Render(new LogEventInfo());
+
+ // Assert
+ Assert.Equal(((HttpStatusCode)200).ToString("x"), result);
+ }
+
+ [Fact]
+ public void StatusCode_Set_Renderer_InvalidFormat()
+ {
+ // Arrange
+ var (renderer, httpContext) = CreateWithHttpContext();
+ renderer.Format = "invalid";
+
+ httpContext.Response.StatusCode.Returns(200);
+
+ // Act
+ string result = renderer.Render(new LogEventInfo());
+
+ // Assert
+ Assert.Equal("", result);
+ }
+
+ [Fact]
+ public void StatusCode_Set_Renderer_UpperCaseIntegerFormat()
+ {
+ // Arrange
+ var (renderer, httpContext) = CreateWithHttpContext();
+ renderer.Format = "D";
+
+ httpContext.Response.StatusCode.Returns(200);
+
+ // Act
+ string result = renderer.Render(new LogEventInfo());
+
+ // Assert
+ Assert.Equal("200", result);
+ }
+
[Theory]
[InlineData(0, false)]
[InlineData(99, false)]
[InlineData(100, true)]
[InlineData(599, true)]
[InlineData(600, false)]
- public void Only_Render_Valid_StatusCodes(int statusCode, bool shouldBeRendered)
+ public void Only_Render_Valid_StatusCodes_DefaultFormat(int statusCode, bool shouldBeRendered)
{
// Arrange
var (renderer, httpContext) = CreateWithHttpContext();
@@ -45,5 +142,141 @@ public void Only_Render_Valid_StatusCodes(int statusCode, bool shouldBeRendered)
Assert.Empty(result);
}
}
+
+ [Theory]
+ [InlineData(0, false)]
+ [InlineData(99, false)]
+ [InlineData(100, true)]
+ [InlineData(599, true)]
+ [InlineData(600, false)]
+ public void Only_Render_Valid_StatusCodes_EnumFormatF(int statusCode, bool shouldBeRendered)
+ {
+ // Arrange
+ var (renderer, httpContext) = CreateWithHttpContext();
+ renderer.Format = "f";
+ httpContext.Response.StatusCode.Returns(statusCode);
+
+ // Act
+ string result = renderer.Render(new LogEventInfo());
+
+ // Assert
+ if (shouldBeRendered)
+ {
+ Assert.Equal(((HttpStatusCode)statusCode).ToString(), result);
+ }
+ else
+ {
+ Assert.Empty(result);
+ }
+ }
+
+
+ [Theory]
+ [InlineData(0, false)]
+ [InlineData(99, false)]
+ [InlineData(100, true)]
+ [InlineData(599, true)]
+ [InlineData(600, false)]
+ public void Only_Render_Valid_StatusCodes_EnumFormatG(int statusCode, bool shouldBeRendered)
+ {
+ // Arrange
+ var (renderer, httpContext) = CreateWithHttpContext();
+ renderer.Format = "g";
+ httpContext.Response.StatusCode.Returns(statusCode);
+
+ // Act
+ string result = renderer.Render(new LogEventInfo());
+
+ // Assert
+ if (shouldBeRendered)
+ {
+ Assert.Equal(((HttpStatusCode)statusCode).ToString(), result);
+ }
+ else
+ {
+ Assert.Empty(result);
+ }
+ }
+
+ [Theory]
+ [InlineData(0, false)]
+ [InlineData(99, false)]
+ [InlineData(100, true)]
+ [InlineData(599, true)]
+ [InlineData(600, false)]
+ public void Only_Render_Valid_StatusCodes_IntegerFormat(int statusCode, bool shouldBeRendered)
+ {
+ // Arrange
+ var (renderer, httpContext) = CreateWithHttpContext();
+ renderer.Format = "d";
+ httpContext.Response.StatusCode.Returns(statusCode);
+
+ // Act
+ string result = renderer.Render(new LogEventInfo());
+
+ // Assert
+ if (shouldBeRendered)
+ {
+ Assert.Equal($"{statusCode}", result);
+ }
+ else
+ {
+ Assert.Empty(result);
+ }
+ }
+
+ [Theory]
+ [InlineData(0, false)]
+ [InlineData(99, false)]
+ [InlineData(100, true)]
+ [InlineData(599, true)]
+ [InlineData(600, false)]
+ public void Only_Render_Valid_StatusCodes_UpperCaseIntegerFormat(int statusCode, bool shouldBeRendered)
+ {
+ // Arrange
+ var (renderer, httpContext) = CreateWithHttpContext();
+ renderer.Format = "D";
+ httpContext.Response.StatusCode.Returns(statusCode);
+
+ // Act
+ string result = renderer.Render(new LogEventInfo());
+
+ // Assert
+ if (shouldBeRendered)
+ {
+ Assert.Equal($"{statusCode}", result);
+ }
+ else
+ {
+ Assert.Empty(result);
+ }
+ }
+
+ [Theory]
+ [InlineData(0, false)]
+ [InlineData(99, false)]
+ [InlineData(100, true)]
+ [InlineData(599, true)]
+ [InlineData(600, false)]
+ public void Only_Render_Valid_StatusCodes_HexFormat(int statusCode, bool shouldBeRendered)
+ {
+ // Arrange
+ var (renderer, httpContext) = CreateWithHttpContext();
+ renderer.Format = "x";
+ httpContext.Response.StatusCode.Returns(statusCode);
+
+ // Act
+ string result = renderer.Render(new LogEventInfo());
+
+ // Assert
+ if (shouldBeRendered)
+ {
+ Assert.Equal(((HttpStatusCode)statusCode).ToString("x"), result);
+ }
+ else
+ {
+ Assert.Empty(result);
+ }
+ }
}
}