Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Web API request content empty

I have a DelegatingHandler implementation to log request/response content:

public class RequestAndResponseLoggerDelegatingHandler : DelegatingHandler
{
    public IDataAccess Data { get; set; }

    protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
    {
        var started = DateTime.UtcNow;
        var response = await base.SendAsync(request, cancellationToken);
        await Log(started, request, response);
        return response;
    }

    private async Task Log(DateTime start, HttpRequestMessage request, HttpResponseMessage response)
    {
        var finished = DateTime.UtcNow;
        var requestContent = await request.Content.ReadAsStringAsync();
        var responseContent = await response.Content.ReadAsStringAsync();
        var info = new ApiLogEntry(start, finished, requestContent, responseContent, request, response);
        Data.Log(info);
    }
}

but for some reason requestContent is coming up empty. request.Content.Length is confirming that there is content, it's just not being extracted.

Any ideas?

like image 755
David Keaveny Avatar asked Feb 11 '23 11:02

David Keaveny


1 Answers

The request body stream is read and bound into parameters and as a result of binding, the stream has been positioned to the end. That is why it is coming as empty. If you seek to the beginning before request.Content.ReadAsStringAsync(), it should work. Instead of that, you can simply read the request body first before binding happens, some thing like this.

public class RequestAndResponseLoggerDelegatingHandler : DelegatingHandler
{
    public IDataAccess Data { get; set; }

    protected override async Task<HttpResponseMessage> SendAsync(
                            HttpRequestMessage request, 
                                 CancellationToken cancellationToken)
    {
        var started = DateTime.UtcNow;
        var requestContent = await request.Content.ReadAsStringAsync();

        var response = await base.SendAsync(request, cancellationToken);

        var responseContent = await response.Content.ReadAsStringAsync();
        await Log(started, request, response, requestContent, responseContent);
        return response;
    }

    private async Task Log(DateTime start, HttpRequestMessage request, 
                             HttpResponseMessage response, string requestContent, 
                                string responseContent)
    {
        var finished = DateTime.UtcNow;           
        var info = new ApiLogEntry(start, finished, requestContent, responseContent, 
                                        request, response);
        Data.Log(info);
    }
}
like image 50
Badri Avatar answered Feb 14 '23 00:02

Badri