Возврат нескольких файлов из действия MVC
Итак, у меня есть приложение MVC 3, в котором есть несколько мест, где текстовый файл генерируется и возвращается в действие, используя:
return File(System.Text.Encoding.UTF8.GetBytes(someString),
"text/plain", "Filename.extension");
и это работает сказочно. Теперь у меня есть ситуация, когда я пытаюсь вернуть пару файлов аналогичным образом. В представлении у меня есть ссылка для действия, например "Нажмите здесь, чтобы получить эти 2 файла", и я хотел бы, чтобы оба файла были загружены так же, как один файл загружен в приведенном выше фрагменте кода.
Как я могу это достичь? Очень много искал и даже не видел этого вопроса в любом месте...
Ответы
Ответ 1
Опираясь на идею Йогендры Сингха и используя DotNetZip:
var outputStream = new MemoryStream();
using (var zip = new ZipFile())
{
zip.AddEntry("file1.txt", "content1");
zip.AddEntry("file2.txt", "content2");
zip.Save(outputStream);
}
outputStream.Position = 0;
return File(outputStream, "application/zip", "filename.zip");
Обновление 2019/04/10: как указывал @Alex, архивирование поддерживается изначально, начиная с .NET Framework 4.5, от JitBit и других:
using (var memoryStream = new MemoryStream())
{
using (var archive = new ZipArchive(memoryStream, ZipArchiveMode.Create, true))
{
var file1 = archive.CreateEntry("file1.txt");
using (var streamWriter = new StreamWriter(file1.Open()))
{
streamWriter.Write("content1");
}
var file2 = archive.CreateEntry("file2.txt");
using (var streamWriter = new StreamWriter(file2.Open()))
{
streamWriter.Write("content2");
}
}
return File(memoryStream.ToArray(), "application/zip", "Images.zip")
}
Ответ 2
Я бы посоветовал создать файл zip
для включения обоих файлов с помощью шагов (ALGORITHM):
- Создайте Zip файл и добавьте нужные файлы в zip
- Верните zip файл, содержащий все необходимые файлы из действия
Синтаксис Java (только для понимания)
FileOutputStream fos = new FileOutputStream("downloadFile.zip");
ZipOutputStream zos = new ZipOutputStream(new BufferedOutputStream(fos));
zos.putNextEntry(new ZipEntry("Filename1.extension"+));
//write data in FileName1.extension
zos.write(contentBuffer1, 0, len);
zos.putNextEntry(new ZipEntry("Filename2.extension"));
//write data in FileName2.extension
zos.write(contentBuffer2, 0, len);
//write other files.....
zos.close();
После создания файла zip
верните вновь созданный файл zip
для загрузки.
return File("downloadFile.zip");
. DOT Net Equivalent с помощью DotNetZip
var os = new MemoryStream();
using (var zip = new ZipFile())
{
//write the first file into the zip
zip.AddEntry("file1.txt", "content1");
//write the second file into the zip
zip.AddEntry("file2.txt", "content2");
//write other files.....
zip.Save(os);
}
outputStream.Position = 0;
return File(outputStream, "application/zip", "filename.zip");
Надеюсь, это поможет!
Ответ 3
Извините, что столкнулся с старым вопросом, но...
Другой альтернативой может быть инициировать несколько загрузок файлов с использованием JavaScript и обслуживать файлы в двух разных методах действий на стороне ASP.NET.
Вы говорите, что у вас есть ссылка:
В представлении у меня есть ссылка действия, например "Нажмите здесь, чтобы получить эти 2 файлы"
Итак, сделайте эту ссылку следующим образом:
<a href="#" onclick="downloadFile(url1); downloadFile(url2);">Click to get 2 files</a>
<script src="download.js"></script>
Я использую download.js
script найденный здесь, но вы можете найти множество других других опций, см. этот вопрос SO: запуск загрузки файла с помощью JavaScript, например
Ответ 4
Посмотрите на это SO-решение: MVC Streaming Zip File
Преимущество этого решения заключается в том, что он передает файл клиенту.
Я только что реализовал это решение пару дней назад, и он работал фантастически.