Передача архива с сервера в.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]

Другие вопросы по тегам