Khateeb321
Khateeb321

Reputation: 2104

Downloaded files in Angularjs doesn't saves properly

My Web API method either returns the single file or zip file having multiple files. This is Web API implementation.

        public HttpResponseMessage Download([FromUri] List<string> fileNames)
        {
            try
            {
                HttpResponseMessage result = new HttpResponseMessage(HttpStatusCode.OK);
                if (fileNames.Count > 1)
                {
                    List<string> filePaths = new List<string>();
                    
                    MemoryStream memoryStreamOfFile = new MemoryStream();

                    using (ZipFile zip = new ZipFile())
                    {
                        foreach (var fileName in fileNames)
                        {
                            zip.AddFile(HttpRuntime.AppDomainAppPath + @"\Uploaded\" + fileName);
                        }
                        zip.Save(memoryStreamOfFile);
                        memoryStreamOfFile.Seek(0, SeekOrigin.Begin);
                        result.Content = new StreamContent(memoryStreamOfFile);
                        result.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment");
                        result.Content.Headers.ContentDisposition.FileName = "files.zip";
                        result.Content.Headers.ContentType =
                            new MediaTypeHeaderValue("application/octet-stream");
                        return result;
                    }
                }

                if (!string.IsNullOrEmpty(fileNames[0]))
                {
                    string filePath = HttpRuntime.AppDomainAppPath + @"\Uploaded\" + fileNames[0];
                    
                    var stream = new FileStream(filePath, FileMode.Open, FileAccess.Read);
                    result.Content = new StreamContent(stream);
                    result.Content.Headers.ContentType =
                        new MediaTypeHeaderValue("application/octet-stream");
                    return result;
                }
                return this.Request.CreateResponse(HttpStatusCode.NotFound, "File not found.");
            }
            catch (Exception ex)
            {
                return this.Request.CreateResponse(HttpStatusCode.InternalServerError, ex);
            }
        }

This method is working completely fine, I'm sure because when I request to this method through "Advanced Rest Client", a Google Chrome extension, file gets downloaded and works perfectly.

But when I request this method through Angularjs service call, file doesn't open. Image files give me following error

enter image description here

following for PDF

enter image description here

and following for zip

enter image description here

From Advance Rest Client behavior is expected, but not with Angularjs. Following is my Angular code

"download": {
        method: "GET",
        url: "api/files/Download/",
        params: { fileNames: "@fileNames" },
        responseType: "arraybuffer",
        headers: {
            'Content-Type': "application/octet-stream"
        }
 }    

return fileManagerClientService.download({ fileNames: fileName })
                .$promise
                .then(function (data) {
                    
                    console.log(data);
                    appInfo.setInfo({ message: "files downloaded successfully" });

                    try {
                        var blob = new Blob([data]);

                        if (typeof (fileName) == "string")
                            FileSaver.saveAs(blob, fileName);
                        else
                            FileSaver.saveAs(blob, "AllFiles.zip");

                    } catch (ex) {
                        console.log(ex);
                    }
                },

Please tell me what I'm missing on the Angular side? I've tried many code snippets but they didn't work!

Upvotes: 1

Views: 533

Answers (1)

Khateeb321
Khateeb321

Reputation: 2104

So guys, the issue is resolved by replacing $resource with $http call. Here is the working code,

function download(fileName) {
            appInfo.setInfo({ busy: true, message: "loading files" });
            

            return $http({
                method: "GET",
                url: "api/files/Download/",
                params: { fileNames: fileName },
                responseType: "arraybuffer"
            }).then(function (data) {
                appInfo.setInfo({ message: "files downloaded successfully" });

                try {
                    var blob = new Blob([data.data]);

                    if (typeof (fileName) == "string")
                        FileSaver.saveAs(blob, fileName);
                    else
                        FileSaver.saveAs(blob, "AllFiles.zip");

                } catch (ex) {
                    console.log(ex);
                }
            }, function (error) {

            });
        }

This is working code, I hope someone would have a better solution using $resource and why it wasn't working with $resource anyway.

Upvotes: 2

Related Questions