Skip to content

Instantly share code, notes, and snippets.

@bronumski
Last active June 21, 2021 14:31
Show Gist options
  • Save bronumski/2564f03e30a810012ee5890d04fff28b to your computer and use it in GitHub Desktop.
Save bronumski/2564f03e30a810012ee5890d04fff28b to your computer and use it in GitHub Desktop.
/// <summary>
/// <see cref="DelegatingHandler"/> that can be used to capture the actual outbound request and the returned
/// response. These are logged by default to the console but can also be routed to an action. This can be useful
/// for tests that use a <see cref="HttpClient"/> to call a fake service.
/// </summary>
/// <example>
/// new HttpClient(new LoggingDelegatingHandler(new HttpClientHandler()));
/// </example>
public class LoggingDelegatingHandler : DelegatingHandler
{
private readonly Action<string> _loggerAction;
/// <summary>
/// Logs all requests and responses to the console.
/// </summary>
/// <param name="innerHandler"></param>
public LoggingDelegatingHandler(HttpMessageHandler innerHandler)
: this(innerHandler, Console.WriteLine) { }
/// <summary>
/// Logs all requests and responses to the supplied action.
/// </summary>
/// <param name="innerHandler"></param>
/// <param name="loggerAction"></param>
public LoggingDelegatingHandler(HttpMessageHandler innerHandler, Action<string> loggerAction)
: base(innerHandler) => _loggerAction = loggerAction;
protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
await LogRequest( request );
var response = await base.SendAsync(request, cancellationToken);
await LogResponse( response );
return response;
}
private async Task LogResponse( HttpResponseMessage response ) =>
_loggerAction((await LogContent(StartLog(response), response.Content)).ToString());
private async Task LogRequest( HttpRequestMessage request ) =>
_loggerAction((await LogContent(StartLog(request), request.Content)).ToString());
private StringBuilder StartLog(object obj) =>
new StringBuilder(obj switch
{
HttpRequestMessage _ => "Request -> ",
HttpResponseMessage _ => "Response -> "
})
.Append(obj).AppendLine();
private async Task<StringBuilder> LogContent(StringBuilder stringBuilder, HttpContent content)
{
if( content != null )
{
stringBuilder.AppendLine( await content.ReadAsStringAsync() );
}
return stringBuilder;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment