private readonly RequestDelegate _next;
/// <summary>
/// set trace context
/// </summary>
/// <param name="next"></param>
public RequestResponseLoggerMiddleware(RequestDelegate next)
{
_next = next;
}
public async Task Invoke(HttpContext context)
{
if (context != null)
{
var endpoint = context.GetEndpoint();
if (endpoint != null)
{
var attribute = endpoint.Metadata.OfType<MarkAttribute>().SingleOrDefault();
if(attribute != null)
{
if (!attribute.IsEnable)
return;
//enable stream can be read more than once
context.Request.EnableBuffering();
var originalResponseStream = context.Response.Body;
//do not use using to dispose reader
var requestReader = new StreamReader(context.Request.Body);
var requestStr = await requestReader.ReadToEndAsync();
Activity.Current?.SetTag("Request", requestStr);
//set request stream pointer
context.Request.Body.Position = 0;
//response.Stream cant be read, set a new stream to read
using var memoryStream = new MemoryStream();
context.Response.Body = memoryStream;
//execute api
await _next(context);
memoryStream.Position = 0;
var responseReader = new StreamReader(memoryStream);
var responseStr = await responseReader.ReadToEndAsync();
Activity.Current?.SetTag("Response", responseStr);
memoryStream.Position = 0;
await memoryStream.CopyToAsync(originalResponseStream);
context.Response.Body = originalResponseStream;
return;
}
}
}
await _next(context);
}