我找到了控制响应缓冲的好方法。但我需要禁用REQUEST缓冲。
问题的简短版本:
我发现后台有一个缓冲区,用来填充请求数据。断点指示请求方法不会暂停这个过程,所以它显然是由后台线程完成的。我遵循了一些指示(例如关闭FormValueProviderFactory(,但它们并不能阻止这种行为。
问题的长期版本:
我已经在这里实现了代码。
该示例创建了一个名为DisableFormValueModelBindingAttribute的筛选器属性,文档声称该属性阻止将文件加载到内存中,但它没有这种效果。请求开始流式传输后,过滤器被击中。
但是我发现整个请求仍然被缓冲到内存中。它达到了请求内存限制,并开始存储在磁盘中,但这会导致服务器的磁盘空间不足。我只有几百MB可以使用,因为该服务托管在docker中。我真正需要的是将多部分请求缓冲到我可以读取它的程度。
我正在使用.net核心2.1和AspNetCore 2.1.1
关于Request.EnableBuffering的一点注记
名称不正确-请求总是被缓冲的,这实际上是启用请求倒带。
关于IHttpBufferingFeature.DisableBuffering的说明
这太令人着迷了。它没有实现细节。Oblete标签上写着
[Obsolete("See IHttpRequestBodyFeature or IHttpResponseBodyFeature DisableBuffering", error: true)]
但是IHttpRequestBodyFeature不存在。
令人失望,因为当这个答案出现时,我很兴奋!
更多信息
经过一些实验,我发现了一些东西。我将请求从控制器中移到了中间件中。
app.Use ((context, next) =>
{
var Request = context.Request;
if (MultipartRequestHelper.IsMultipartContentType(Request.ContentType))
{
// a breakpoint here doesn't stop the upload
var path = Request.Path;
// ...
但是我发现有一个后台线程正在填充请求缓冲区。我在中间件中设置了一个断点,但我仍然可以看到后台发生的上传。请求缓冲区仍在填充。
答案可能与可以对HttpRequestFeature进行的可能配置有关。
进一步信息
在UseKestrel的回调中,您可以配置限制,并且有一个限制
称为";MaxRequestBufferSize";
但默认情况下这是1MB。很明显,它不对缓冲到磁盘的完整请求负责。
我还发现了一个关于缓冲可配置的github问题,主要是抱怨它不可配置。这并不能使我充满信心。
在撰写本文时,这是不可能的
IHttpRequestBodyFeature
没有实现或公开,因此没有一个方法可供我们调用以禁用请求缓冲。只有一种方法可以使用DisableBuffering
方法禁用IHttpResponseBodyFeature中的响应缓冲。
我在GitHub上搜索了IHttpRequestBodyFeature
的最小结果https://github.com/search?q=IHttpRequestBodyFeature&type=进一步支持接口还不可用或还没有向我们公开的想法。另一方面,如果你搜索IHttpResponseBodyFeature
,你会从dotnet和aptnetcore得到很多结果。
我建议为IHttpRequestBodyFeature
提交一个在此处不可用的问题:https://github.com/dotnet/aspnetcore/issues
我找不到在IHttpResponseFeature
中禁用请求缓冲的方法。没有提供method
来执行此操作。但是,有了IHttpResponseBodyFeature
,就有了一个method
来禁用响应缓冲;下面是一个例子:
-
添加以下命名空间
using Microsoft.AspNetCore.Http.Features;
-
在想要禁用响应缓冲的IActionResults中,使用
DisableBuffering()
方法:
选择退出响应的写缓冲
var bufferingFeature2 = HttpContext.Features.Get<IHttpResponseBodyFeature>();
bufferingFeature2?.DisableBuffering();