繁体   English   中英

在 ASP.NET Core FromHeader 导致 Request.Body 被完全读取

[英]In ASP.NET Core FromHeader is causing the Request.Body to be fully read

在 ASP.Net Core 中,我有这个操作方法:

[HttpPost("things")]
[DisableFormValueModelBinding]
public async Task<IActionResult> UploadAsync()
{
    using StreamReader sr = new StreamReader(Request.Body);
    string body = await sr.ReadToEndAsync().ConfigureAwait(false);
    int bodyLength = body.Length;
    return Ok();
}

它工作得很好。 正文是流式传输的,我可以全部阅读。 但是,一旦我尝试获得 header:

[HttpPost("things")]
[DisableFormValueModelBinding]
public async Task<IActionResult> UploadAsync(
    [FromHeader(Name = "X-Test")] string test)
{
    using StreamReader sr = new StreamReader(Request.Body);
    string body = await sr.ReadToEndAsync().ConfigureAwait(false);
    int bodyLength = body.Length;
    return Ok();
}

主体已经在 stream 的末尾,并且读取了零字节。 显然,我正在阅读 header,它不应该影响请求正文。 如果我将代码更改为:

[HttpPost("things")]
[DisableFormValueModelBinding]
public async Task<IActionResult> UploadAsync()
{
    string test = Request.Headers["X-Test"].First();
    using StreamReader sr = new StreamReader(Request.Body);
    string body = await sr.ReadToEndAsync().ConfigureAwait(false);
    int bodyLength = body.Length;
    return Ok();
}

动作又开始起作用了,我什至正在阅读 header。 如果我切换回 FromHeader 它会再次失败。 显然,FromHeader 正在内部做一些与请求正文混淆的事情。

对我来说,与 FromHeader 一起工作很重要,这样 Swagger 才能继续工作。 如果没有 FromHeader,我无法在 Swagger 中指定 header 值。

所以我开始搜索,我找到了这个页面:

https://github.com/dotnet/aspnetcore/issues/18087

似乎其他人在使用 FromQuery 时遇到了类似的问题,有些人通过以下方式解决了这个问题:

结果:System.IO.IOException:Stream 的意外结束,内容可能已被另一个组件读取。 在 Microsoft.AspNetCore.WebUtilities.MultipartReaderStream.ReadAsync(字节 [] 缓冲区,Int32 偏移量,Int32 计数,CancellationToken 取消令牌)

并且是“固定”的: [DisableFormValueModelBinding] 和 factory.RemoveType();

程序集 Microsoft.AspNetCore.WebUtilities,版本=3.1.0.0 程序集 Microsoft.AspNetCore.Mvc.Core,版本=3.1.0.0

...

仔细检查您的 DisableFormValueModelBindingAttribute 代码以确保它正在删除 FormFileValueProviderFactory。

我去尝试看看它是否有什么不同,但我在 NuGet 中看到的这些库的最新版本是 2.2.0 和 2.2.5,这是我安装的最新稳定版本。 而且这些库中还不存在这种类型(FormFileValueProviderFactory)。 使用 ILSpy 进行检查表明它确实不存在。 VS 确实显示我的目标框架是 .NET Core 3.1。

无论如何,我什至不确定这会解决我的问题。

有人对我有什么建议吗?

谢谢!

我已经确认如果我在DisableFormValueModelBindingAttributeValueProviderFactories中搜索FormFileValueProviderFactory ,只需执行Where(p => p.GetType().Name == "FormFileValueProviderFactory").FirstOrDefault()即可找到它。 然后,如果我将其从工厂列表中删除,一切正常。

所以现在的问题变成了为什么我不能引用那个类型。 由于我已拉出类型,因此我可以查看所引用的程序集,它是C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App\3.1.10\Microsoft.AspNetCore.Mvc.Core.dll 这意味着它甚至根本没有使用 NuGet,而是使用了这个组件。 因此,当我发现为什么以这种方式设置这个项目时,我开始删除旧的和不必要的 NuGet 引用。 帮助程序库中有一些 ASP.NET 核心 MVC 实用程序,包括DisableFormValueModelBindingAttribute 该库当前配置为netstandard2.1 ,这就是无法引用 ASP.NET 核心内容的原因。

要解决这个问题,我所要做的就是将目标框架更改为netcoreapp3.1并将其添加到引用 ASP.NET 核心:

<ItemGroup>
  <FrameworkReference Include="Microsoft.AspNetCore.App" />
</ItemGroup>

现在一切正常。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM