9

I'm receiving and http post request, with raw body, and I'm trying to read the http body Stream into a String.

I'm using the basic Hello World web project generated by the dotnet web command. According to the documentation:

In the .NET Framework 4 and earlier versions, you have to use methods such as BeginRead and EndRead to implement asynchronous I/O operations. These methods are still available in the .NET Framework 4.5 to support legacy code; however, the new async methods, such as ReadAsync, WriteAsync, CopyToAsync, and FlushAsync, help you implement asynchronous I/O operations more easily.

So I tried with the ReadAsync method with something like this:

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    // _controller = controller;
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }

    app.Run(async (context) =>
    {

        using (Stream Body = context.Request.Body) {
            byte[] result;
            result = new byte[context.Request.Body.Length];
            await context.Request.Body.ReadAsync(result, 0, (int)context.Request.Body.Length);

            String body = System.Text.Encoding.UTF8.GetString(result).TrimEnd('\0');

            _log.LogInformation($"Body: {body}");
        }
        await context.Response.WriteAsync("Hello World!");
    });
}

But I'm getting the following error:

info: Microsoft.AspNetCore.Hosting.Internal.WebHost1 Request starting HTTP/1.1 POST http://localhost:5000/json/testing?id=2342&name=sas application/json 82 fail: Microsoft.AspNetCore.Server.Kestrel[13] Connection id "0HL7ISBH941G6", Request id "0HL7ISBH941G6:00000001": An unhandled exception was thrown by the application. System.NotSupportedException: Specified method is not supported. at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.FrameRequestStream.get_Length() at mtss.ws.Startup.<b__4_0>d.MoveNext() in /home/inspiron/devel/apps/dotnet/mtss-ws/Startup.cs:line 47

-- update

I could get something working setting the size of the buffer to Int16.MaxValue, but that way I can't read bodies larger that 32k.

3
  • Can you show us the entire code, how youre getting the data in the first place? Commented Sep 3, 2017 at 15:24
  • sure, there you go Commented Sep 3, 2017 at 15:52
  • Only async functions working! This code had ran in my app. <code> using (Stream Body = request.Body) { byte[] result; // int len = request.Body.Length ---> Error result = new byte[UInt16.MaxValue]; await request.Body.ReadAsync(result, 0, UInt16.MaxValue); return System.Text.Encoding.UTF8.GetString(result).TrimEnd('\0'); } </code> Commented Nov 21, 2023 at 21:28

2 Answers 2

11

I found this question at SO that helped my find the following solution:

app.Run(async (context) =>
{

    string body = new StreamReader(context.Request.Body).ReadToEnd();
    _log.LogInformation($"Body: {body}");
    _log.LogInformation($"Body.Length: {body.Length}");

    await context.Response.WriteAsync("Hello World!");
});

and the async version is pretty much alike:

    string body = await new StreamReader(context.Request.Body).ReadToEndAsync();

Not sure if this is the best way to do it...

Sign up to request clarification or add additional context in comments.

Comments

6

I, too, had issues with ReadAsync stopping short of the full content. My solution is similar to the one offered by opensas, however, I did it with a "using" so the StreamReader's dispose method would be called automatically. I also added the UTF8 encoding option to the StreamReader.

using StreamReader reader = new StreamReader (Request.Body, Encoding.UTF8);
string body = await reader.ReadToEndAsync ();

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.