Skip to content

Instantly share code, notes, and snippets.

@srafay
Created July 17, 2022 06:10
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save srafay/479dff91f56d2e43d2da174a03c76679 to your computer and use it in GitHub Desktop.
Save srafay/479dff91f56d2e43d2da174a03c76679 to your computer and use it in GitHub Desktop.
Trying to create Layout Renderer for accessing NavigationManager Uri (Blazor)
using System.Text;
using NLog.LayoutRenderers;
namespace NLog.Web.LayoutRenderers
{
/// <summary>
/// Inject NavigationManager class which provides an abstraction for querying and managing URI navigation (for ASP.NET Core 3.0, 3.1, 5.0, 6.0, 7.0)
/// </summary>
/// <para>Example usage of ${aspnet-navigation-manager}:</para>
/// <example>
/// <code lang="NLog Layout Renderer">
/// ${aspnet-navigation-manager}
/// </code>
/// </example>
[LayoutRenderer("aspnet-navigation-manager")]
public class AspNetNavigationManagerLayoutRenderer : AspNetLayoutRendererBase
{
/// <summary>
/// The object for the key in HttpContext.Items for the NavigationManager
/// </summary>
internal static readonly object NLogNavigationManagerKey = new object();
/// <summary>Renders the NavigationManager</summary>
/// <param name="builder">The <see cref="T:System.Text.StringBuilder" /> to append the rendered data to.</param>
/// <param name="logEvent">Logging event.</param>
protected override void DoAppend(StringBuilder builder, LogEventInfo logEvent)
{
var httpContext = HttpContextAccessor.HttpContext;
if (httpContext == null)
{
return;
}
var items = httpContext.Items;
if (items == null)
{
return;
}
#if !ASP_NET_CORE
if (items.Contains(NLogNavigationManagerKey))
{
return;
}
#else
if (items.ContainsKey(NLogNavigationManagerKey))
{
return;
}
#endif
builder.Append(items[NLogNavigationManagerKey] as string);
}
}
}
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using NLog.Common;
using NLog.Web.LayoutRenderers;
#if ASP_NET_CORE3
using Microsoft.AspNetCore.Components;
#endif
namespace NLog.Web
{
/// <summary>
/// This class is to intercept the HTTP pipeline and to allow additional logging of the following
///
/// Navigation Manager
///
/// Usage: app.UseMiddleware&lt;NLogNavigationManagerMiddleware&gt;(); where app is an IApplicationBuilder
///
/// Inject the NLogNavigationManagerMiddlewareOptions in the IoC if wanting to override default values for constructor
/// </summary>
public class NLogNavigationManagerMiddleware
{
private readonly RequestDelegate _next;
private readonly NLogNavigationManagerMiddlewareOptions _options;
/// <summary>
/// Initializes new instance of the <see cref="NLogNavigationManagerMiddleware"/> class
/// </summary>
/// <remarks>
/// Use the following in Startup.cs:
/// <code>
/// public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
/// {
/// app.UseMiddleware&lt;NLog.Web.NLogNavigationManagerMiddleware&gt;();
/// }
/// </code>
/// </remarks>
public NLogNavigationManagerMiddleware(RequestDelegate next, NLogNavigationManagerMiddlewareOptions options = default)
{
_next = next;
_options = options ?? NLogNavigationManagerMiddlewareOptions.Default;
}
#if ASP_NET_CORE3
/// <summary>
/// This allows interception of the HTTP pipeline for querying and managing URI navigation
/// </summary>
/// <param name="context">The HttpContext</param>
/// <param name="navigationManager">The NavigationManager</param>
/// <returns></returns>
public async Task Invoke(HttpContext context, NavigationManager navigationManager)
{
if (ShouldCaptureNavigationManager(context))
{
var requestUri = string.Empty;
try
{
requestUri = navigationManager.Uri;
}
catch
{
InternalLogger.Debug("NLogNavigationManagerMiddleware: NavigationManager not initialized");
}
if (!string.IsNullOrEmpty(requestUri))
{
context.Items[AspNetRequestPostedBodyLayoutRenderer.NLogPostedRequestBodyKey] = requestUri;
}
}
// Execute the next class in the HTTP pipeline, this can be the next middleware or the actual handler
await _next(context).ConfigureAwait(false);
}
#else
/// <summary>
/// This allows interception of the HTTP pipeline for querying and managing URI navigation
/// </summary>
/// /// <param name="context">The HttpContext</param>
/// <returns></returns>
public async Task Invoke(HttpContext context)
{
InternalLogger.Debug("NLogNavigationManagerMiddleware: ASP.NET Core version not supported, skipping middleware execution");
// Execute the next class in the HTTP pipeline, this can be the next middleware or the actual handler
await _next(context).ConfigureAwait(false);
}
#endif
private bool ShouldCaptureNavigationManager(HttpContext context)
{
// Perform null checking
if (context == null)
{
InternalLogger.Debug("NLogNavigationManagerMiddleware: HttpContext is null");
return false;
}
return _options.ShouldCapture(context);
}
}
}
using System;
using Microsoft.AspNetCore.Http;
using NLog.Common;
namespace NLog.Web
{
/// <summary>
/// Contains the configuration for the NLogNavigationManagerMiddleware
/// </summary>
public class NLogNavigationManagerMiddlewareOptions
{
/// <summary>
/// The default configuration
/// </summary>
internal static readonly NLogNavigationManagerMiddlewareOptions Default = new NLogNavigationManagerMiddlewareOptions();
/// <summary>
/// The default constructor
/// </summary>
public NLogNavigationManagerMiddlewareOptions()
{
ShouldCapture = DefaultCapture;
}
/// <summary>
/// If this returns true, the navigation manager will be captured
/// Defaults to true for ASP.NET Core versions 3.0, 3.1, 5.0, 6.0, 7.0
/// </summary>
/// <returns></returns>
public Predicate<HttpContext> ShouldCapture { get; set; }
/// <summary>
/// The default predicate for ShouldCapture. Returns true for ASP.NET Core versions 3.0, 3.1, 5.0, 6.0, 7.0
/// </summary>
private bool DefaultCapture(HttpContext context)
{
#if ASP_NET_CORE3
InternalLogger.Debug("NLogNavigationManagerMiddleware: ASP.NET version supported, capturing NavigationManager");
return true;
#else
InternalLogger.Debug("NLogNavigationManagerMiddleware: ASP.NET version not supported, not capturing NavigationManager");
return false;
#endif
}
}
}
1. First Configure NLog for Blazor application.
2. Once NLog is configured, add the following files for creating a new layouy renderer (for Navigation Manager)
- AspNetNavigationManagerLayoutRenderer.cs (in Layout Renderers)
- NLogNavigationManagerMiddlewareOptions.cs
- NLogNavigationManagerMiddleware.cs
3. In Program.cs or Startup.cs (depending on your .NET Core version), use the middleware app.UseMiddleware<NLogNavigationManagerMiddleware>();
4. In NLog.config file, you can access the navigation-manager-uri property as ${event-properties:item=navigation-manager-uri}.
layout="${event-properties:item=navigation-manager-uri} ${message}"
OR
layout="${when:when='${event-properties:item=navigation-manager-uri}'!='':Inner=${event-properties:item=navigation-manager-uri} }${message}"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment