Skip to content

Instantly share code, notes, and snippets.

@chrisbewz
Forked from mrshridhara/MessageLoggingHandler.cs
Created November 25, 2025 14:51
Show Gist options
  • Select an option

  • Save chrisbewz/a8939d3ec3140c89f2d5af64cd28fa64 to your computer and use it in GitHub Desktop.

Select an option

Save chrisbewz/a8939d3ec3140c89f2d5af64cd28fa64 to your computer and use it in GitHub Desktop.
DelegatingHandler to log request and response of a Web API call.
using System;
using System.Net.Http;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
/// <summary>
/// </summary>
public class MessageLoggingHandler : DelegatingHandler
{
/// <summary>
/// Sends an HTTP request to the inner handler to send to the server as an asynchronous operation.
/// </summary>
/// <param name="request">The HTTP request message to send to the server.</param>
/// <param name="cancellationToken">A cancellation token to cancel operation.</param>
/// <returns>
/// Returns <see cref="T:System.Threading.Tasks.Task`1"/>. The task object representing the asynchronous operation.
/// </returns>
protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
// Record the start time.
var startTime = DateTime.Now;
// Execute the request, this does not block.
var response = base.SendAsync(request, cancellationToken);
// Once the response is processed asynchronously, log the data.
response.ContinueWith(responseMessage => LogData(startTime, DateTime.Now, request, responseMessage.Result, responseMessage.Exception));
return response;
}
private static void LogData(DateTime startTime, DateTime endTime, HttpRequestMessage request, HttpResponseMessage response, Exception exception)
{
// Is this Web API call?
if (request.RequestUri.AbsoluteUri.Contains("/api/") == false)
{
// Return without doing anything.
return;
}
var loggingInfo = new LoggingInfo { StartTime = startTime, EndTime = endTime, Url = request.RequestUri.AbsoluteUri };
request
.Content
.ReadAsByteArrayAsync()
.ContinueWith(requestContentTask => { loggingInfo.Request = Encoding.UTF8.GetString(requestContentTask.Result); })
.ContinueWith
(
requestContentTask =>
{
if (exception == null)
{
response
.Content
.ReadAsByteArrayAsync()
.ContinueWith(responseContentTask => { loggingInfo.Response = Encoding.UTF8.GetString(responseContentTask.Result); })
.ContinueWith(responseContentTask => LogData(loggingInfo));
}
else
{
loggingInfo.Exception = exception;
LogData(loggingInfo);
}
}
);
}
private static void LogData(LoggingInfo loggingInfo)
{
// Log data to appropriate storage.
}
/// <summary>
/// </summary>
public class LoggingInfo
{
/// <summary>
/// Gets or sets the request.
/// </summary>
/// <value>
/// The request.
/// </value>
public string Request { get; set; }
/// <summary>
/// Gets or sets the response.
/// </summary>
/// <value>
/// The response.
/// </value>
public string Response { get; set; }
/// <summary>
/// Gets or sets the end time.
/// </summary>
/// <value>
/// The end time.
/// </value>
public DateTime EndTime { get; set; }
/// <summary>
/// Gets or sets the start time.
/// </summary>
/// <value>
/// The start time.
/// </value>
public DateTime StartTime { get; set; }
/// <summary>
/// Gets or sets the exception.
/// </summary>
/// <value>
/// The exception.
/// </value>
public Exception Exception { get; set; }
/// <summary>
/// Gets or sets the URL.
/// </summary>
/// <value>
/// The URL.
/// </value>
public string Url { get; set; }
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment