【问题标题】:Transmitting Zipped file from server in .Net在.Net中从服务器传输压缩文件
【发布时间】:2018-07-18 22:25:15
【问题描述】:

我正在编写一个小型 Web 应用程序,部分功能是能够将日志从服务器下载到用户的文件系统。我能够压缩现有日志,但无法让压缩文件夹传输。我在这里浏览了许多其他类似的问题,但还没有根据其中任何一个问题来解决问题。

这是我目前正在尝试的代码:

.Net 控制器

[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 错误。

【问题讨论】:

  • 您不应该在 MVC 操作方法中直接写入响应。而且您无法将文件写入响应并在单个操作方法中返回 JSON。你只能做其中之一。
  • @mason 很好。我已经更新了代码,但还没有工作

标签: asp.net response.transmitfile


【解决方案1】:

@mason 注意到您的代码有问题。您正在尝试返回两件事,文件和状态。

通过HTTP返回码检查操作状态。

您可以使用IActionResult 接口作为返回类型,这样您就可以正确处理事情。给该方法一个File 作为返回类型,如果一切正常,它将返回您的文件以及所需的所有标题。如果出现问题,您可以返回BadRequest("Error Message")

File 返回类型接受 FileStream 作为参数,其中包含您的原始数据、文件的 Mime 类型和文件名

要做到这一点,请执行以下步骤

  • 将方法返回类型更改为FileResult
  • 创建一个变量,将您的文件内容作为流接收或使用using 语句
  • 创建一个byte数组来分配文件内容(如果你试图返回文件流,你会得到文件关闭的错误,因为在retun发生之前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]

【讨论】:

  • 感谢您的回复。我一直在关注您的编辑。我将签名更改为 ActionResult(因为它不喜欢 BadRequest')。当它从调用返回时,它指向 ajax 代码中的 Error 块。
  • 我应该补充一点,我将 ajax 调用中的内容类型更改为 application/zip,但它仍然返回 500 错误
  • .net抛出的异常中Message的内容是什么?如果您在 ajax 中执行 alert(response.data),您将收到错误
  • 它说的是Cannot access a closed file。它正在返回到 ajax 调用,并且没有被控制器的 try/catch 捕获。
  • 我的愚蠢错误...文件在返回之前被处理。我已经用额外的步骤更新了答案
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-02-03
  • 1970-01-01
  • 1970-01-01
  • 2015-11-17
相关资源
最近更新 更多