Skip to content

Instantly share code, notes, and snippets.

@mrshridhara
Created July 7, 2014 13:44
Show Gist options
  • Save mrshridhara/0f6a4ed1277dbc467f75 to your computer and use it in GitHub Desktop.
Save mrshridhara/0f6a4ed1277dbc467f75 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; }
}
}
@serefbilge
Copy link

serefbilge commented Sep 2, 2021

 Wait() should be called after ContinueWith methods, otherwise error comes out. Please check the page: https://stackoverflow.com/questions/26087935/why-do-i-have-to-wait-for-the-continuation

                 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)).Wait();                                                           
				        }
				        else
				        {
					        loggingInfo.Exception = exception;
					        LogData(loggingInfo);
				        }
			        }
		        ).Wait();

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment