简体   繁体   中英

Trying to download zip file from server using AngularJs and c# webapi

I know that posts with similar titles exist, but it doesn't work for me its how I try to achieve that:

WebApi

public async Task<HttpResponseMessage> ExportAnalyticsData([FromODataUri] int siteId, [FromODataUri] string start, [FromODataUri] string end) {
    DateTime startDate = Date.Parse(start);
    DateTime endDate = Date.Parse(end);

    using (ZipFile zip = new ZipFile()) {
        using (var DailyLogLanguagesCsv = new CsvWriter(new StreamWriter("src"))) {
            var dailyLogLanguages = await _dbContext.AggregateDailyLogSiteObjectsByDates(siteId, startDate, endDate).ToListAsync();
            DailyLogLanguagesCsv.WriteRecords(dailyLogLanguages);
            zip.AddFile("src");
        }


        using (var DailyLogSiteObjectsCsv = new CsvWriter(new StreamWriter("src"))) {
            var dailyLogSiteObjects = await _dbContext.AggregateDailyLogSiteObjectsByDates(siteId, startDate, endDate).ToListAsync();
            DailyLogSiteObjectsCsv.WriteRecords(dailyLogSiteObjects);
            zip.AddFile("src");
        }

        zip.Save("src");
        HttpResponseMessage result = null;
        var localFilePath = HttpContext.Current.Server.MapPath("src");

        if (!File.Exists(localFilePath)) {
            result = Request.CreateResponse(HttpStatusCode.Gone);
        } else {
            // Serve the file to the client
            result = Request.CreateResponse(HttpStatusCode.OK);
            result.Content = new StreamContent(new FileStream(localFilePath, FileMode.Open, FileAccess.Read));
            result.Content.Headers.ContentDisposition = new System.Net.Http.Headers.ContentDispositionHeaderValue("attachment");
            result.Content.Headers.ContentDisposition.FileName = "Analytics";
        }
        return result;
    }
}

AngularJs

$scope.exportData = function () {
    apiService.dailyLog.exportAnalyticsData($scope.siteId, $scope.startDate, $scope.finishDate).then(function (response) {
        debugger;
        var blob = new Blob([response.data], { type: "application/zip" });
        saveAs(blob, "analytics.zip");
    })
};

function saveAs(blob, fileName) {
    var url = window.URL.createObjectURL(blob);
    var doc = document.createElement("a");
    doc.href = url;
    doc.download = fileName;
    doc.click();
    window.URL.revokeObjectURL(url);
}

And when I download a file I get information that the file is damaged. It only happens when I return zip file. It works well for csv .

After @wannadream suggestions and edited my code

                else
            {
                // Serve the file to the client
                result = Request.CreateResponse(HttpStatusCode.OK);
                result.Content = new StreamContent(new FileStream(localFilePath, FileMode.Open, FileAccess.Read));
                result.Content.Headers.ContentDisposition = new System.Net.Http.Headers.ContentDispositionHeaderValue("attachment");
                result.Content.Headers.ContentDisposition.FileName = "Analytics";
                result.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
            }

I have such problem when i try to open downloaded zip . 在此处输入图片说明

zip.AddFile("src"); and then zip.Save("src"); ? It does not make sense.

You are zipping 'src' with target name 'src'. Try another name for zip file.

zip.Save("target")

var localFilePath = HttpContext.Current.Server.MapPath("target");

Try set this:

result.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");

Try accessing the WebAPI controller action through a normal browser, and see if the ZIP it downloads can open. If it can't, then your problem is in your WebAPI.

I resolve it by set a type responseType

{ type: "application/octet-stream", responseType: 'arraybuffer' }

and the same thing in my apiService

$http.get(serviceBase + path), {responseType:'arraybuffer'});

This can be done using DotNetZip and set the response type as arraybuffer, check below code for complete understanding.

1.WebApi Controller

        [HttpPost]
        [Route("GetContactFileLink")]
        public HttpResponseMessage GetContactFileLink([FromBody]JObject obj)
        {
                string exportURL = "d:\\xxxx.text";//replace with your filepath

                var fileName =  obj["filename"].ToObject<string>();

                exportURL = exportURL+fileName;

                var resullt = CreateZipFile(exportURL);


                return resullt;
        }

private HttpResponseMessage CreateZipFile(string directoryPath)
        {
            try
            {
                HttpResponseMessage response = Request.CreateResponse(HttpStatusCode.OK);

                using (ZipFile zip = new ZipFile())
                {
                    zip.AlternateEncodingUsage = ZipOption.AsNecessary;
                    zip.AddFile(directoryPath, "");
                    //Set the Name of Zip File.
                    string zipName = String.Format("Zip_{0}.zip", DateTime.Now.ToString("yyyy-MMM-dd-HHmmss"));
                    using (MemoryStream memoryStream = new MemoryStream())
                    {
                        //Save the Zip File to MemoryStream.
                        zip.Save(memoryStream);

                        //Set the Response Content.
                        response.Content = new ByteArrayContent(memoryStream.ToArray());

                        //Set the Response Content Length.
                        response.Content.Headers.ContentLength = memoryStream.ToArray().LongLength;

                        //Set the Content Disposition Header Value and FileName.
                        response.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment");
                        response.Content.Headers.ContentDisposition.FileName = zipName;

                        //Set the File Content Type.
                        response.Content.Headers.ContentType = new MediaTypeHeaderValue("application/zip");
                        return response;
                    }
                }
            }
            catch(Exception ex)
            {
                throw new ApplicationException("Invald file path or file not exsist");
            }
        }

2.Angular component

    function getcontactFileLink(token, params) {

                return $http.post('api/event/GetContactFileLink', params, { headers: { 'Authorization': 'Bearer ' + token, 'CultureCode': cc }, 'responseType': 'arraybuffer' }).then(response);

                function response(response) {
                    return response;
                }
            }

function showcontactfile(item) {
            usSpinnerService.spin('spinner-1');
            var params = {};
            params.filename = item.filename;
            EventListingProcess.getcontactFileLink(accessToken, params).then(function (result) {
                var blob = new Blob([result.data], { type: "application/zip" });
                var fileName = item.filename+".zip";
                var a = document.createElement("a");
                document.body.appendChild(a);
                a.style = "display:none";
                var url = window.URL.createObjectURL(blob);
                a.href = url;
                a.download = fileName;
                a.click();
                window.URL.revokeObjectURL(url);
                a.remove();


            }).catch(function (error) {
                vm.message = frameworkFactory.decodeURI(error.statusText);
                //frameworkFactory.translate(vm, 'message', error.statusText);
            }).finally(function () {
                usSpinnerService.stop('spinner-1');
            });
        }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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