diff --git a/NLog.Web.Tests/LayoutRenderers/AspNetRequestValueLayoutRendererTests.cs b/NLog.Web.Tests/LayoutRenderers/AspNetRequestValueLayoutRendererTests.cs index 1461e490..735409c9 100644 --- a/NLog.Web.Tests/LayoutRenderers/AspNetRequestValueLayoutRendererTests.cs +++ b/NLog.Web.Tests/LayoutRenderers/AspNetRequestValueLayoutRendererTests.cs @@ -112,6 +112,53 @@ public void KeyFoundRendersValue() } } + public class HeaderTests + { + [Fact] + public void NullKeyRendersEmptyString() + { + var httpContext = Substitute.For(); + + var renderer = new AspNetRequestValueLayoutRenderer(); + renderer.HttpContextAccessor = new FakeHttpContextAccessor(httpContext); + renderer.Header = null; + + var result = renderer.Render(new LogEventInfo()); + + Assert.Empty(result); + } + + [Fact] + public void KeyNotFoundRendersEmptyString() + { + var httpContext = Substitute.For(); + + var renderer = new AspNetRequestValueLayoutRenderer(); + renderer.HttpContextAccessor = new FakeHttpContextAccessor(httpContext); + renderer.Header = "key"; + + var result = renderer.Render(new LogEventInfo()); + + Assert.Empty(result); + } + + [Fact] + public void KeyFoundRendersValue() + { + var expectedResult = "value"; + var httpContext = Substitute.For(); + httpContext.Request.Headers.Returns(new NameValueCollection { { "key", expectedResult } }); + + var renderer = new AspNetRequestValueLayoutRenderer(); + renderer.HttpContextAccessor = new FakeHttpContextAccessor(httpContext); + renderer.Header = "key"; + + var result = renderer.Render(new LogEventInfo()); + + Assert.Equal(expectedResult, result); + } + } + public class FormTests { [Fact] diff --git a/NLog.Web.Tests/LayoutRenderers/AspNetSessionValueLayoutRendererTests.cs b/NLog.Web.Tests/LayoutRenderers/AspNetSessionValueLayoutRendererTests.cs index ef2debfc..6438c63f 100644 --- a/NLog.Web.Tests/LayoutRenderers/AspNetSessionValueLayoutRendererTests.cs +++ b/NLog.Web.Tests/LayoutRenderers/AspNetSessionValueLayoutRendererTests.cs @@ -1,7 +1,4 @@ using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; using System.Reflection; using System.Web; using System.Web.SessionState; @@ -12,10 +9,8 @@ namespace NLog.Web.Tests.LayoutRenderers { - public class AspNetSessionValueLayoutRendererTests : IDisposable + public class AspNetSessionValueLayoutRendererTests : TestInvolvingAspNetHttpContext { - - public AspNetSessionValueLayoutRendererTests() { SetUp(); @@ -26,9 +21,8 @@ public void SetUp() SetupFakeSession(); } - public void CleanUp() + protected override void CleanUp() { - Session.Clear(); } @@ -216,35 +210,19 @@ private void ExecTest(string key, object value, object expected, LayoutRenderer /// /// Create Fake Session http://stackoverflow.com/a/10126711/201303 /// - public static void SetupFakeSession() + public void SetupFakeSession() { - var httpRequest = new HttpRequest("", "http://stackoverflow/", ""); - var stringWriter = new StringWriter(); - var httpResponse = new HttpResponse(stringWriter); - var httpContext = new HttpContext(httpRequest, httpResponse); - var sessionContainer = new HttpSessionStateContainer("id", new SessionStateItemCollection(), new HttpStaticObjectsCollection(), 10, true, HttpCookieMode.AutoDetect, SessionStateMode.InProc, false); - httpContext.Items["AspSession"] = typeof(HttpSessionState).GetConstructor( + HttpContext.Items["AspSession"] = typeof(HttpSessionState).GetConstructor( BindingFlags.NonPublic | BindingFlags.Instance, null, CallingConventions.Standard, new[] { typeof(HttpSessionStateContainer) }, null) .Invoke(new object[] { sessionContainer }); - - HttpContext.Current = httpContext; - - } - - /// - /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. - /// - public void Dispose() - { - CleanUp(); } } } diff --git a/NLog.Web.Tests/LayoutRenderers/TestInvolvingAspNetHttpContext.cs b/NLog.Web.Tests/LayoutRenderers/TestInvolvingAspNetHttpContext.cs new file mode 100644 index 00000000..7414a8f1 --- /dev/null +++ b/NLog.Web.Tests/LayoutRenderers/TestInvolvingAspNetHttpContext.cs @@ -0,0 +1,66 @@ +using System; +using System.Collections; +using System.IO; +using System.Reflection; +using System.Web; + +namespace NLog.Web.Tests.LayoutRenderers +{ + public abstract class TestInvolvingAspNetHttpContext : IDisposable + { + protected HttpContext HttpContext; + + protected TestInvolvingAspNetHttpContext() + { + HttpContext = SetupFakeHttpContext(); + HttpContext.Current = HttpContext; + } + + /// + /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. + /// + public void Dispose() + { + CleanUp(); + } + + protected virtual void CleanUp() + { + } + + protected HttpContext SetupFakeHttpContext() + { + var httpRequest = SetUpHttpRequest(); + var stringWriter = new StringWriter(); + var httpResponse = new HttpResponse(stringWriter); + return new HttpContext(httpRequest, httpResponse); + } + + protected virtual HttpRequest SetUpHttpRequest(string query = "") + { + return new HttpRequest("", "http://stackoverflow/", query); + } + + protected void AddHeader(HttpRequest request, string headerName, string headerValue) + { + // thanks http://stackoverflow.com/a/13307238 + var headers = request.Headers; + var t = headers.GetType(); + var item = new ArrayList(); + + t.InvokeMember("MakeReadWrite", BindingFlags.InvokeMethod | BindingFlags.NonPublic | BindingFlags.Instance, + null, + headers, null); + t.InvokeMember("InvalidateCachedArrays", + BindingFlags.InvokeMethod | BindingFlags.NonPublic | BindingFlags.Instance, + null, headers, null); + item.Add(headerValue); + t.InvokeMember("BaseAdd", BindingFlags.InvokeMethod | BindingFlags.NonPublic | BindingFlags.Instance, null, + headers, + new object[] {headerName, item}); + t.InvokeMember("MakeReadOnly", BindingFlags.InvokeMethod | BindingFlags.NonPublic | BindingFlags.Instance, + null, + headers, null); + } + } +} \ No newline at end of file diff --git a/NLog.Web.Tests/NLog.Web.Tests.csproj b/NLog.Web.Tests/NLog.Web.Tests.csproj index 03f83cb5..28c2cb4a 100644 --- a/NLog.Web.Tests/NLog.Web.Tests.csproj +++ b/NLog.Web.Tests/NLog.Web.Tests.csproj @@ -84,6 +84,7 @@ + diff --git a/NLog.Web/LayoutRenderers/AspNetRequestValueLayoutRenderer.cs b/NLog.Web/LayoutRenderers/AspNetRequestValueLayoutRenderer.cs index 33649b50..27fd6c74 100644 --- a/NLog.Web/LayoutRenderers/AspNetRequestValueLayoutRenderer.cs +++ b/NLog.Web/LayoutRenderers/AspNetRequestValueLayoutRenderer.cs @@ -19,6 +19,7 @@ namespace NLog.Web.LayoutRenderers /// ${aspnet-request:querystring=v} /// ${aspnet-request:form=v} /// ${aspnet-request:cookie=v} + /// ${aspnet-request:header=h} /// ${aspnet-request:serverVariable=v} /// /// @@ -56,6 +57,12 @@ public class AspNetRequestValueLayoutRenderer : AspNetLayoutRendererBase /// public string ServerVariable { get; set; } + /// + /// Gets or sets the Headers item to be rendered. + /// + /// + public string Header { get; set; } + /// /// Renders the specified ASP.NET Request variable and appends it to the specified . /// @@ -91,6 +98,15 @@ protected override void DoAppend(StringBuilder builder, LogEventInfo logEvent) { builder.Append(httpRequest.ServerVariables[this.ServerVariable]); } + else if (this.Header != null) + { + string header = httpRequest.Headers[this.Header]; + + if (header != null) + { + builder.Append(header); + } + } else if (this.Item != null) { builder.Append(httpRequest[this.Item]);