如何在使用dot net core 2.0的ReadAsync方法中将http主体获取为字符串

8

我正在接收一个带有原始体的http post请求,尝试将http body流读入一个字符串中。

我正在使用由dotnet web命令生成的基本Hello World Web项目。根据文档

在.NET Framework 4及更早版本中,您必须使用BeginRead和EndRead等方法来实现异步I/O操作。这些方法在.NET Framework 4.5中仍然可用以支持遗留代码;但是,新的async方法(如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!");
    });
}

但是我遇到了以下错误:

信息: Microsoft.AspNetCore.Hosting.Internal.WebHost1 请求开始 HTTP/1.1 POST http://localhost:5000/json/testing?id=2342&name=sas application/json 82 失败: Microsoft.AspNetCore.Server.Kestrel[13] 连接 ID "0HL7ISBH941G6", 请求 ID "0HL7ISBH941G6:00000001": 应用程序引发了未处理的异常。System.NotSupportedException: 不支持指定的方法。 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

-- 更新

我可以通过将缓冲区大小设置为Int16.MaxValue来使某些功能正常工作,但这样我无法读取大于32k的主体。


你能展示一下完整的代码吗?包括你是如何获取数据的? - Afnan Makhdoom
当然,给你。 - opensas
只有异步函数能工作!这段代码在我的应用程序中运行过。<code> using (Stream Body = request.Body) { byte[] result; // int len = request.Body.Length ---> 错误 result = new byte[UInt16.MaxValue]; await request.Body.ReadAsync(result, 0, UInt16.MaxValue); return System.Text.Encoding.UTF8.GetString(result).TrimEnd('\0');} </code> - undefined
2个回答

11

我在stackoverflow找到了一个问题(链接),它帮助我找到了以下解决方案:

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!");
});

而异步版本基本相同:

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

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


4

我也遇到了ReadAsync无法获取完整内容的问题。我的解决方法与opensas提供的类似,但我使用了“using”语句,这样可以自动调用StreamReader的dispose方法。我还在StreamReader中添加了UTF8编码选项。

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接