Search code examples
c#httpcontent

await HttpContent.CopyToAsync() results in empty target stream


I'm trying (and failing) to get the actual JSON string from a Request.HttpContent object.

Here's what I'm doing:

private async Task<string> GetRequestBodyAsString(HttpContent content)
{
    string result;

    using (var streamCopy = new MemoryStream())
    {
        await content.CopyToAsync(streamCopy);
        streamCopy.Position = 0;
        result = new StreamReader(streamCopy).ReadToEnd();
    }

    return result;
}

My problem is, on executing this code, I always get an empty string -- unless I use a breakpoint on the line that sets the streamCopy position to zero, which leads me to think that the code just keeps executing after firing up the CopyToAsync method.

If I change it to:

using (var streamCopy = new MemoryStream())
    {
        do
        {
            count++;
            await content.CopyToAsync(streamCopy);
        } while (streamCopy.Length == 0);

        streamCopy.Position = 0;
        result = new StreamReader(streamCopy).ReadToEnd();
    }

it invariably works correctly (as in, result will contain the JSON, but this smells... foul.

What am I doing wrong here?


Solution

  • I met the same issue and was trying to adopt your solution. But some further googling leads me to a better solution given here. The original code writes to a file but the idea still applies.

    The trick is avoiding using CopyToAsync, but using ReadAsStreamAsync directly. Here is what it looks like after minor changes:

    using (Stream ms = await content.ReadAsStreamAsync())
    {
        using (var reader = new StreamReader(ms))
        {
            return reader.ReadToEnd();
        }
    }