gpt4 book ai didi

c# - 为什么我在尝试将大文件发布到 Core Web API 时收到 404

转载 作者:可可西里 更新时间:2023-11-01 08:43:23 25 4
gpt4 key购买 nike

我对 HttpClient 和 Web API 之间的文件传输非常陌生,所以请原谅我的代码中的任何无知和猜测。我一直在尝试将使用 System.IO.Compression.ZipFile 创建的文件发布到我的 Web API 大约一天,但总是收到 404 响应。如果我使用空流发布,则会调用 API 操作方法,所以我知道 404 是由于内容而不是 URI。

此方法位于尝试发布文件的客户端 WPF 应用程序中:

public async Task PostDirAsync(string localDirPath, string serverDir)
{
var sourcePath = Path.Combine("Temp", Guid.NewGuid() + ".zip");
ZipFile.CreateFromDirectory(localDirPath, sourcePath, CompressionLevel.Fastest, true);
StreamContent streamContent;
using (var fs = File.Open(sourcePath, FileMode.Open))
{
var outStream = new MemoryStream();
await fs.CopyToAsync(outStream);
outStream.Position = 0;
streamContent = new StreamContent(outStream);
}
streamContent.Headers.Add("Content-Type", "application/octet-stream");
var resp = await _client.PostAsync("api/File/PostDir?serverPath={WebUtility.UrlEncode(serverDir)}", streamContent);
}

这是 Web API 中接收帖子的操作方法,但前提是我在尝试发布之前不执行 outStream.Position = 0;:

[HttpPost("PostDir")]
[DisableRequestSizeLimit]
public async Task<IActionResult> PostDir(string serverPath)
{
var zipName = Path.Combine(_config["QuickDrive:TempDir"], Guid.NewGuid() + ".zip");
using (var ms = new MemoryStream())
using (var fileStream = System.IO.File.Create(zipName))
{
await Request.Body.CopyToAsync(ms);
ms.Position = 0;
await ms.CopyToAsync(fileStream);
}
return Ok();
}

action 方法被调用并在空流中无错误地运行,但是因为它写入一个空文件而非常无用。我做错了什么?

最佳答案

如评论中所述,您的第一个问题是未使用 Stream.Position = 0 重置文件复制中涉及的 Stream 实例。我知道您已经进行了这些更改,但我只想强调这是一个分为两部分的解决方案。

那么,第二部分:

在您的示例代码中,您添加了 [DisableRequestSizeLimit] 注释以绕过默认的 ASP.NET Core 2.0+ Kestrel 请求限制。但是,IIS 也有一个限制,默认情况下为 30MB。当超过此大小限制时,IIS 本身会生成 404 响应,这就是您所看到的。

This answer解释了如何使用自定义 Web.config 更改此限制(为了完整性包含在下面):

<?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.webServer>
<security>
<requestFiltering>
<!-- 1 GB -->
<requestLimits maxAllowedContentLength="1073741824" />
</requestFiltering>
</security>
</system.webServer>
</configuration>

作为旁注:

除非有特殊原因,否则您可以避免在代码中使用 MemoryStream,只需将 fs 直接传递到 new StreamContent(. ..)。您可以对 Request.Body 流执行类似的操作,并将其直接复制到输出 FileStream 中。这最终会是:

public async Task PostDirAsync(string localDirPath, string serverDir)
{
var sourcePath = Path.Combine("Temp", Guid.NewGuid() + ".zip");
ZipFile.CreateFromDirectory(localDirPath, sourcePath, CompressionLevel.Fastest, true);

var streamContent = new StreamContent(File.Open(sourcePath, FileMode.Open));
streamContent.Headers.Add("Content-Type", "application/octet-stream");
var resp = await _client.PostAsync("api/File/PostDir?serverPath={WebUtility.UrlEncode(serverDir)}", streamContent);
}

还有:

[HttpPost("PostDir")]
[DisableRequestSizeLimit]
public async Task<IActionResult> PostDir(string serverPath)
{
var zipName = Path.Combine(_config["QuickDrive:TempDir"], Guid.NewGuid() + ".zip");
using (var fileStream = System.IO.File.Create(zipName))
await Request.Body.CopyToAsync(fileStream );
return Ok();
}

关于c# - 为什么我在尝试将大文件发布到 Core Web API 时收到 404,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50737448/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com