在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();
}
它工作得很好。身体是流动的,我可以把它全部读出来。然而,一旦我试图获得一个标题:
[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();
}
正文已经在流的末尾,并且读取了零个字节。很明显,我读的是一个标题,它不应该影响请求正文。如果我将代码更改为:
[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();
}
动作又开始了,我甚至在读标题。如果我切换回FromHeader,它将再次失败。显然,FromHeader在内部做了一些事情,扰乱了请求体。
对我来说,用FromHeader实现这一点很重要,这样Swagger才能继续工作。没有FromHeader,我无法在Swagger中指定标头值。
所以我开始搜索,发现了这个页面:
https://github.com/dotnet/aspnetcore/issues/18087
似乎其他人在使用FromQuery时也遇到了类似的问题,有些人通过以下方式解决了问题:
结果:System.IO.IOException:流意外结束,内容可能已被另一个组件读取。在Microsoft.AspNetCore.WebUtilities.MultipartReaderStream.ReadAsync(Byte[]缓冲区,Int32偏移量,Int32计数,CancellationToken取消令牌(
并且是";固定的";与:[DisableFormValueModelBinding]和工厂。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。
无论如何,我甚至不确定这是否能解决我的问题。
有人对我有什么建议吗?
谢谢!
我已经确认,如果我在DisableFormValueModelBindingAttribute
的ValueProviderFactories
中搜索FormFileValueProviderFactory
,我只需执行Where(p => p.GetType().Name == "FormFileValueProviderFactory").FirstOrDefault()
即可找到它。然后,如果我把它从工厂列表中删除,一切都会正常工作。
所以现在的问题变成了为什么我不能引用那个类型。由于我已经拉起了类型,我可以查看被引用的程序集,它是C:Program FilesdotnetsharedMicrosoft.AspNetCore.App3.1.10Microsoft.AspNetCore.Mvc.Core.dll
。这意味着它甚至根本没有使用NuGet,而是使用这个程序集。因此,当我发现为什么这个项目是这样设置的时候,我开始删除旧的和不必要的NuGet引用。助手库中有一些ASP.NET核心MVC实用程序,包括DisableFormValueModelBindingAttribute
。此库当前配置为netstandard2.1
,这就是为什么不能引用ASP.NET Core内容的原因。
为了解决这个问题,我所要做的就是将目标框架更改为netcoreapp3.1
,并将其添加到引用ASP.NET Core:
<ItemGroup>
<FrameworkReference Include="Microsoft.AspNetCore.App" />
</ItemGroup>
现在一切正常。