Reputation: 2104
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
following for PDF
and following for zip
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
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