如何使用ReadAsync将http主体变为dot net core 2.0中的String

ope*_*sas 5 c# stream .net-core asp.net-core .net-core-2.0

我正在接收和http post请求,带有raw body,我正在尝试将http body Stream读入String.

我正在使用dotnet web命令生成的基本Hello World Web项目.根据文件:

在.NET Framework 4和早期版本中,您必须使用BeginRead和EndRead等方法来实现异步I/O操作.这些方法仍可在.NET Framework 4.5中使用,以支持遗留代码; 但是,新的异步方法(如ReadAsync,WriteAsync,CopyToAsync和FlushAsync)可帮助您更轻松地实现异步I/O操作.

所以我尝试使用ReadAsync方法,如下所示:

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!");
    });
}
Run Code Online (Sandbox Code Playgroud)

但是我收到以下错误:

info:Microsoft.AspNetCore.Hosting.Internal.WebHost 1 请求启动HTTP/1.1 POST http:// localhost:5000/json/testing?id = 2342&name = sas application/json 82 fail:Microsoft.AspNetCore.Server.Kestrel [13 ]连接ID"0HL7ISBH941G6",请求ID"0HL7ISBH941G6:00000001":应用程序抛出了未处理的异常.System.NotSupportedException:不支持指定的方法.at mtss.ws.Startup的Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.FrameRequestStream.get_Length().在/ home/inspiron/devel/apps/dotnet/mtss-ws中的<b__4_0> d.MoveNext() /Startup.cs:line 47

- 更新

我可以得到一些工作将缓冲区的大小设置为Int16.MaxValue,但这样我就无法读取大于32k的体.

ope*_*sas 6

我在SO处发现了这个问题,帮助我找到了以下解决方案:

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!");
});
Run Code Online (Sandbox Code Playgroud)

和异步版本非常相似:

    string body = await new StreamReader(context.Request.Body).ReadToEndAsync();
Run Code Online (Sandbox Code Playgroud)

不确定这是否是最好的方法...


小智 5

我也遇到了 ReadAsync 无法获取完整内容的问题。我的解决方案与opensas提供的解决方案类似,但是,我使用“using”来实现,因此 StreamReader 的 dispose 方法将被自动调用。我还向 StreamReader 添加了 UTF8 编码选项。

using StreamReader reader = new StreamReader (Request.Body, Encoding.UTF8);
string body = await reader.ReadToEndAsync ();
Run Code Online (Sandbox Code Playgroud)