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.
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...
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 ();
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With