Как упоминалось в комментариях, ваша первая проблема заключалась в том, что экземпляры Stream
, связанные с копированием файлов, не сбрасывались с помощью Stream.Position = 0
.Я знаю, что вы уже внесли эти изменения, но я просто хочу подчеркнуть, что это решение состоит из двух частей.
Итак, вторая часть:
В вашем примере кода вы 'Мы добавили аннотацию [DisableRequestSizeLimit]
, чтобы обойти ограничения по умолчанию для запросов Kestrel ASP.NET Core 2.0+.Тем не менее, IIS также устанавливает ограничение, которое по умолчанию составляет 30 МБ.Когда этот предел размера превышен, сам IIS генерирует ответ 404. Это то, что вы видите.
Этот ответ объясняет, как изменить этот предел с помощью пользовательского 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();
}