繁体   English   中英

从Web API返回时Zip损坏了吗?

[英]Corrupted Zip while returning from Web API?

在我的MVC项目中,我有一个对Web API的AJAX调用。

我发送了一系列文档的路由, API(应该)将它们压缩并返回zip文件

self.zipDocs = function (docs, callback) {
    $.ajax({
        url: "../SharedAPI/documents/zip",
        type: "POST",
        data: docs,
        contentType: "application/json",
        success: function (data) {
            var zip = new JSZip(data);
            var content = zip.generate({ type: "blob" });
            saveAs(content, "example.zip");
        },
        error: function (data) {
            callback(data);
        }
    });
}

还有我在WebAPI上的ZipDocs函数(使用DotNetZip库):

[HttpPost]
    [Route("documents/zip")]
    public HttpResponseMessage ZipDocs([FromBody] string[] docs)
    {

        using (var zipFile = new ZipFile())
        {
            zipFile.AddFiles(docs, false, "");
            return ZipContentResult(zipFile);
        }
    }

    protected HttpResponseMessage ZipContentResult(ZipFile zipFile)
    {
        // inspired from http://stackoverflow.com/a/16171977/92756
        var pushStreamContent = new PushStreamContent((stream, content, context) =>
        {
           zipFile.Save(stream);
            stream.Close(); // After save we close the stream to signal that we are done writing.
        }, "application/zip");

        return new HttpResponseMessage(HttpStatusCode.OK) { Content = pushStreamContent };
    }

但是,当Zip返回时,出现以下错误:

未捕获的错误:损坏的zip:缺少16053个字节。

真正奇怪的是,当我将zip文件保存到磁盘上时, 它会正确保存,并且可以毫无问题打开该文件!

我究竟做错了什么? 我错过了什么吗? 请帮忙!

提前致谢。

两件事情:

1 / $.ajax处理文本响应,并尝试(utf-8)解码内容:您的zip文件不是文本,您将获得损坏的内容。 jQuery 不支持二进制内容,因此您需要使用上一个链接并在jQuery上添加ajax传输或直接使用XmlHttpRequest。 对于xhr,您需要设置xhr.responseType = "blob"并从xhr.response读取该blob。

2 /假设您的js代码段是整个函数,则您(尝试)获取二进制内容,解析zip文件,重新生成,然后将内容提供给用户。 您可以直接给出结果:

// with xhr.responseType = "arraybuffer"
var arraybuffer = xhr.response;
var blob = new Blob([arraybuffer], {type:"application/zip"});
saveAs(blob, "example.zip");

// with xhr.responseType = "blob"
var blob = xhr.response;
saveAs(blob, "example.zip");

编辑:例子:

jquery.binarytransport.js (任何可以下载Blob或ArrayBuffer的库都可以)

$.ajax({
  url: "../SharedAPI/documents/zip",
  dataType: 'binary', // to use the binary transport
  // responseType:'blob', this is the default
  // [...]
  success: function (blob) {
    // the result is a blob, we can trigger the download directly
    saveAs(blob, "example.zip");
  }
  // [...]
});

使用原始XMLHttpRequest,您可以看到此问题 ,只需添加一个xhr.responseType = "blob"即可获得一个blob。

我从未使用过C#,但从我的了解中可以看出, [FromBody]对数据格式非常敏感,第一种解决方案在您的情况下应该更容易实现。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM