【发布时间】:2019-11-30 12:33:03
【问题描述】:
当我使用 Postman 尝试将大文件上传到我的服务器(使用 .NET Core 2.2 编写)时,Postman 立即显示 HTTP Error 404.13 - Not Found 错误:The request filtering module is configured to deny a request that exceeds the request content length
但是当我使用我的代码上传那个大文件时,它会卡在发送文件的线路上。
我的客户代码:
public async void TestUpload() {
StreamContent streamContent = new StreamContent(File.OpenRead("D:/Desktop/large.zip"));
streamContent.Headers.Add("Content-Disposition", "form-data; name=\"file\"; filename=\"large.zip\"");
MultipartFormDataContent multipartFormDataContent = new MultipartFormDataContent();
multipartFormDataContent.Add(streamContent);
HttpClient httpClient = new HttpClient();
Uri uri = new Uri("https://localhost:44334/api/user/testupload");
try {
HttpResponseMessage httpResponseMessage = await httpClient.PostAsync(uri, multipartFormDataContent);
bool success = httpResponseMessage.IsSuccessStatusCode;
}
catch (Exception ex) {
}
}
我的服务器代码:
[HttpPost, Route("testupload")]
public async Task UploadFile(IFormFileCollection formFileCollection) {
IFormFileCollection formFiles = Request.Form.Files;
foreach (var item in formFiles) {
using (var stream = new FileStream(Path.Combine("D:/Desktop/a", item.FileName), FileMode.Create)) {
await item.CopyToAsync(stream);
}
}
}
我的客户端代码卡在HttpResponseMessage httpResponseMessage = await httpClient.PostAsync(uri, multipartFormDataContent) 行,而服务器没有收到任何请求(我使用断点来确保这一点)。
文件越大卡住的时间越长。查看任务管理器,我可以看到我的客户端程序使用了高 CPU 和磁盘,因为它实际上正在将文件上传到服务器。过了一会儿,代码移动到下一行,即
bool success = httpResponseMessage.IsSuccessStatusCode
然后通过阅读响应内容,我得到了与 Postman 完全相同的结果。
现在我想知道如何立即得到错误以便能够及时通知用户,我不想等待很长时间。
请注意,当我使用 Postman 上传大文件时,我的服务器也没有收到任何请求。我想我遗漏了一些东西,也许我的客户端代码有问题。
编辑:实际上我认为这是客户端错误。但如果是服务器端错误,那对我来说仍然没有太大意义。因为,让我理清思路。我想创建一个可以跨项目使用的小助手类,也许我也可以与我的朋友分享。所以我认为它应该能够像 Postman 一样,尽快确定错误。如果 Postman 可以,我也可以。
EDIT2:奇怪的是,今天我发现 Postman 事先不知道服务器是否接受大请求,我上传了一个大文件,我看到它实际上将整个文件发送到服务器,直到它得到响应。现在我不再相信自己了,为什么我认为邮递员会提前知道错误,我一定是愚蠢的。但这确实意味着我找到了一种比 Postman 做得更好的方法,所以我认为这个问题可能对某人有用。
【问题讨论】:
-
我怀疑邮递员正在使用 http 1.1,这是块模式,而您的 c# 正在使用 http 1.0,这是流模式。我会使用像wireshark或fiddler这样的嗅探器,并将邮递员请求与c#请求进行比较以查看差异。
-
您的服务器将接收您从 Postman 发送的请求,它只是没有到达您的代码,因为它在管道的早期被拒绝了。您需要更改一些配置以允许大请求。
-
@dezfowler 我知道如何允许大请求。但我的意思是我希望我的代码像 Postman 一样运行,我不会对我的服务器进行任何更改,因为这不是原因。
-
不正确。您的服务器是原因。客户端发送请求,然后等待服务器响应。在某些时候,请求最终会超时,但在此之前,服务器会 100% 中止并发送错误响应。否则,客户端只会等到超时阈值。
-
@peanut 我并不是说你的服务器是这个问题的原因,只是如果你想看到请求通过你需要在服务器端更改一些东西。我认为这可能是因为您没有在流内容上设置 Content-Length 标头。您应该从文件系统中获取文件长度并设置标题。否则 StreamContent 可能正在读取整个文件,以便首先确定长度。它不知道流的来源,并且能够以不同的方式获得长度。
标签: c# asp.net-core postman