Передача архива с сервера в.Net
Я пишу небольшое веб-приложение, и часть его функций заключается в том, чтобы загружать журналы с сервера в файловую систему пользователя. Я могу заархивировать существующие журналы, но мне не удается получить заархивированную папку для передачи. Я просмотрел много других подобных вопросов здесь, но до сих пор не заставил их работать на основе любого из них.
Вот код, который я сейчас пытаюсь:
.Net Controller
[HttpPost]
public ActionResult DownloadLogs()
{
string path = System.Configuration.ConfigurationManager.AppSettings["LogPath"];
try
{
Log.Information("Closing current logger. AudtiLog: {auditLog}", true);
Log.CloseAndFlush();
string startPath = path;
string zipPath = "C:\\my_folder\\result.zip";
string extractPath = path + "extract";
//deleting existing zips
if (System.IO.File.Exists(zipPath))
System.IO.File.Delete(zipPath);
if (System.IO.Directory.Exists(extractPath))
System.IO.Directory.Delete(extractPath, true);
ZipFile.CreateFromDirectory(startPath, zipPath);
ZipFile.ExtractToDirectory(zipPath, extractPath);
FileInfo file = new FileInfo(zipPath);
using (FileStream filestream = new FileStream(zipPath, FileMode.Open))
{
return File(filestream, "application/zip", "ServerLogZip.zip");
}
}
catch (Exception ex)
{
Log.Error("Error occurred when downloading server logs. Error: {Error}; AuditLog: {auditLog}", ex.Message, true);
return Json(new { result = "error" });
}
}
Javascript
function DownloadLogs() {
$.ajax({
type: "POST",
url: "/ManageServer/DownloadLogs",
contentType: "application/zip",
success: function (response) {
alert("Success")
},
error: function (response) {
alert("Error");
}
});
}
Всякий раз, когда я запускаю его, он архивирует журналы в одну папку, проходит через Response
часть кода успешно, но ничего не происходит. Я пробовал отладку и пошаговое выполнение кода, но пока не нашел ответа. Я также попробовал Response.WriteFile
метод также. Неудачно.
Изменить Я обновил код для возврата ActionResult
и вернул File
, В настоящее время он возвращает ошибку 500 с сервера.
1 ответ
У вас проблема с кодом, как заметил @mason. Вы пытаетесь вернуть две вещи, файл и статус.
Статус операции должен быть проверен через коды возврата HTTP.
Вы можете использовать IActionResult
интерфейс как тип возвращаемого значения, так что вы можете обрабатывать вещи правильно. Дать метод File
в качестве возвращаемого типа, и если все в порядке, он вернет ваш файл со всеми необходимыми заголовками. Если что-то пойдет не так, вы можете вернуть BadRequest("Error Message")
;
File
возвращаемый тип принимает в качестве параметров FileStream, который будет содержать ваши необработанные данные, Mime-тип файла и имя файла
Для этого выполните следующие шаги
- Измените тип возврата метода на
FileResult
- Создайте переменную, которая будет получать содержимое вашего файла в виде потока или использовать
using
заявление - Создать
byte
массив для размещения содержимого файла (если вы попытаетесь вернуть файловый поток, вы получите сообщение об ошибке закрытия файла, поскольку оператор using закрывается до того, как произойдет повторная установка) - Возвратите данные как это
return File(byteArray, "application/zip", "ServerLogZip.zip");
Образец
try{
// Do things to prepare your file
using(FileStream filestream = new FileStream(zipPath,FileMode.Open))
{
byte[] zipBytes= new byte[filestream.Length];
filestream.Read(PhotoBytes, 0, PhotoBytes.Length);
return File(zipBytes, "application/zip", "ServerLogZip.zip");
}
}
catch(Exception ex){
return BadRequest("Something gone wrong: " + ex.Message);
}
Я пытался понять, как загрузить этот файл с помощью асинхронного запроса, но в конце концов я понял, что, возможно, вам не нужно такое сложное решение. Вы можете просто позвонить по маршруту, и файл будет загружен.
function DownloadLogs() {
document.location = your_route;
}
Для правильной работы вы также должны изменить декоратор метода вашего метода C# с [HttpPost]
в [HttpGet]