【问题标题】:How to download ByteArrayContent of HttpResponseMessage as zip如何将 HttpResponseMessage 的 ByteArrayContent 下载为 zip
【发布时间】:2015-04-16 17:15:26
【问题描述】:

我在客户端使用 Web Api (C#) 和 angular.js。 我需要下载服务器响应内容(zip 的 ByteArrayContent)。 我在服务器上有这个方法:

public HttpResponseMessage Download(DownloadImagesInput input)
        {
            if (!string.IsNullOrEmpty(input.ImageUrl))
            {
                byte[] imageBytes = GetByteArrayFromUrl(input.ImageUrl);

                ZipManager manager = new ZipManager();
                HttpResponseMessage result = new HttpResponseMessage(HttpStatusCode.OK);
                byte[] zipBytes;


                zipBytes = string.IsNullOrEmpty(input.QrCode) ? manager.ZipFiles(imageBytes) 
                                                              : manager.ZipFiles(imageBytes, input.QrCode);

                result.Content = new ByteArrayContent(zipBytes);


                result.Content.Headers.ContentType =
                                    new MediaTypeHeaderValue("application/zip");
                return result;

            }

            return new HttpResponseMessage(HttpStatusCode.InternalServerError);
        }

ZipManager 是我的服务,它只返回 zip 文件的字节数组。 我需要在客户端下载这个 zip 存档。 这是我的客户:

$apiService.downloadZip({ 'ImageUrl': $scope.currentImage, 'QrCode': str }).then(function (response) {

            var hiddenElement = document.createElement('a');

            hiddenElement.href = 'data:application/zip,' + response.data;
            hiddenElement.target = '_blank';
            hiddenElement.download = 'images.zip';
            hiddenElement.click();
        });

结果:下载 zip 文件但我无法打开它,文件格式无效

在服务器上创建的zip文件是好的,我只是通过直接将他从服务器保存到磁盘来检查它... 需要帮助。

【问题讨论】:

    标签: javascript c# asp.net angularjs asp.net-web-api


    【解决方案1】:

    我找到了解决办法:

    服务器:

    1.将字节数组转换为base64字符串:

    string base64String = System.Convert.ToBase64String(zipBytes, 0, zipBytes.Length);
    

    2.result内容是StringContent而不是ByteArrayContent:

    result.Content = new StringContent(base64String);
    

    客户:

    $apiService.downloadZip({ 'ImageUrl': $scope.currentImage, 'QrCode': str }).then(function (response) {
                var hiddenElement = document.createElement('a');
    
                hiddenElement.href = 'data:application/octet-stream;charset=utf-8;base64,' + response.data;
                hiddenElement.target = '_blank';
                hiddenElement.download = 'images.zip';
                hiddenElement.click();
            });
    

    【讨论】:

    • 我无法在 IE11 或 edge 中下载文件。这个逻辑可能需要稍微调整一下。
    【解决方案2】:

    下面是我用来下载任何类型文件的函数代码

    var downloadFile = function (filename) {
        enableSpinner();
        var ifr = document.createElement('iframe');
        ifr.style.display = 'none';
        document.body.appendChild(ifr);
        ifr.src = document.location.pathname + "api/FileIo/Download?filename='" + escape(filename) + "'";
        ifr.onload = function () {
            document.body.removeChild(ifr);
            ifr = null;
        };
    };
    

    及其服务器端代码

    [HttpGet]
            public HttpResponseMessage Download(string filename)
            {
                filename = filename.Replace("\\\\", "\\").Replace("'", "").Replace("\"", "");
                if (!char.IsLetter(filename[0]))
                {
                    filename = filename.Substring(2);
                }
    
                var fileinfo = new FileInfo(filename);
                if (!fileinfo.Exists)
                {
                    throw new FileNotFoundException(fileinfo.Name);
                }
    
                try
                {
                    var excelData = File.ReadAllBytes(filename);
                    var result = new HttpResponseMessage(HttpStatusCode.OK);
                    var stream = new MemoryStream(excelData);
                    result.Content = new StreamContent(stream);
                    result.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
                    result.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment")
                    {
                        FileName = fileinfo.Name
                    };
                    return result;
                }
                catch (Exception ex)
                {
                    return Request.CreateResponse(HttpStatusCode.ExpectationFailed, ex);
                }
            }
    

    您可以用 zip 部分替换 excel 部分并完成...

    【讨论】:

      猜你喜欢
      • 2017-08-09
      • 2015-01-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-03-07
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多