Web API request content empty
10,316
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);
}
}
Author by
David Keaveny
Updated on June 17, 2022Comments
-
David Keaveny almost 2 years
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?
-
Anatolii Humennyi about 7 yearsBut after that the binding always returns null object because the stream was already read to the end. How to reset request stream to the beginning?
-
Sean Mahan over 5 yearsThere's a way to access the actual input stream form the request properties, shared here: stackoverflow.com/a/11902185/1108969