#c# #http #.net-core #content-length #fileresult
#c# #http #.net-ядро #длина содержимого #файловый результат
Вопрос:
Привет, я использую код из этого поста в блоге :
https://blog.stephencleary.com/2016/11/streaming-zip-on-aspnet-core.html
Для того, чтобы передавать zip-файл в потоковом режиме .Сетевое ядро. Я заставил это работать, но поскольку я не добавил заголовок длины содержимого в ответ, когда я не загружаю zip-файл, он не будет показывать ход загрузки в Chrome. Поскольку я заранее знаю размер zip-файла, я действительно могу установить заголовок длины содержимого с помощью метода SetHeadersAndLog https://learn.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.mvc.internal.fileresultexecutorbase.setheadersandlog?view=aspnetcore-2.0
но когда я это делаю, у меня возникает следующая ошибка :
System.InvalidOperationException: Response Content-Length mismatch: too many bytes written (144144633 of 144144627)
.
Есть идеи, почему ответ не такой длины, как zip-файл? Вот код для обслуживания файла:
this._httpContext.Response.ContentType = "application/octet-stream";
this._httpContext.Response.Headers.Add("Access-Control-Expose-Headers", "Content-Disposition");
this._httpContext.Response.ContentLength = estimatedFileSize;
FileCallbackResult result = new FileCallbackResult(new MediaTypeHeaderValue("application/octet-stream"), estimatedFileSize, async (outputStream, _) =>
{
using (ZipArchive zip = new ZipArchive(outputStream, ZipArchiveMode.Create, false))
{
foreach (string filepath in Directory.EnumerateFiles(existingDirectory.FullName, "*.*", SearchOption.AllDirectories))
{
string relativepath = filepath.Replace(existingDirectory.FullName "\", string.Empty);
ZipArchiveEntry zipEntry = zip.CreateEntry(relativepath, CompressionLevel.Fastest);
using (Stream zipstream = zipEntry.Open())
{
using (Stream stream = new FileStream(filepath, FileMode.Open))
{
await stream.CopyToAsync(zipstream);
}
}
}
}
})
{
FileDownloadName = $"{package.FileName}.zip",
};
Комментарии:
1. Покажите, где вы заполняете
estimatedFileSize
.2. @mxmissile У меня уже есть zip-файл на диске (который я создал тем же способом, что и здесь, с тем же уровнем сжатия) Я получаю его как FileInfo с помощью
Directory.EnumerateFile(filename).firstordefault()
затем я проверяю его длину.3. Вы пробовали просто отправить этот файл вместо этого или воссоздать его заново? Разные библиотеки zip имеют разные уровни сжатия.
Ответ №1:
Вам нужно выполнить поиск потока обратно к началу.
Комментарии:
1. это означает: основной поток. Искать(0, SeekOrigin.Begin);