1

I can't seem to set a zip file's name from a web API in a HttpResponseMessage. I can successfully create the zip file using ZipArchive with all its content files, but when downloading it from client side (although it does return and open successfully) the name appears in a 16-byte hexadecimal format like a guid. I would like to set a custom name for my zip file. Where should I do this?

Setting the ContentDisposition doesn't work:

responseMessage.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment")
{
     FileName = attachmentName
};

From the client side using Angular2+ I return the file as a blob:

DownloadAtachment(url: string): Observable<Blob> { 
 const requestHeaders = new Headers(
    {
        'Content-Type', 'application/json',
        'Accept', 'application/zip'
    },
 );

 let options = new RequestOptions({ headers: requestHeaders });
 let args: RequestOptionsArgs = {headers: options, withCredentials:false, responseType: ResponseContentType.ArrayBuffer};

 return this._http.get(url, args)
    .map(response => {
        return new Blob([response.blob()], { type: 'application/zip'});
    });
}
meJustAndrew
  • 6,011
  • 8
  • 50
  • 76
Jnr
  • 1,504
  • 2
  • 21
  • 36

3 Answers3

1

I recommend using file-saver js library (check Angular 2 Best approach to use FileSaver.js) or ngx-filesaver, more info here https://www.npmjs.com/package/ngx-filesaver

kriss
  • 976
  • 17
  • 27
  • This seems like a work-around, although it could be a solution if the web API does not allow an zip file name to be set in the `HttpResponseMessage`. – Jnr Mar 14 '19 at 13:18
  • @Jnr try to add header responseMessage.Content.Headers.Add("x-filename", attachmentName); – kriss Mar 14 '19 at 13:23
  • also change responseType: ResponseContentType.ArrayBuffer to ResponseContentType.Blob – kriss Mar 14 '19 at 13:25
  • Tried both of those, to no avail. – Jnr Mar 14 '19 at 13:34
1

I'm still not entirely sure why the HttpResponseMessage headers are not used, but I just used a different way to handle the response. So instead of using the following to open the blob:

const fileurl = URL.createObjectURL(res);
window.open(fileurl, '_self');

I used a @ViewChild to access an invisible anchor tag to handle the click and set attachment name:

const fileurl = URL.createObjectURL(res);
const link = this.zipClick.nativeElement as HTMLAnchorElement;
link.href = fileurl;
link.donwload = "Name.zip";
link.click();
window.URL.revokeObjectURL(fileurl);
Jnr
  • 1,504
  • 2
  • 21
  • 36
0

If you don't need to download it with Angular's HttpClient, you can simple create an <a [href]="url" target="_blank">Download zip</a> in the template. It maybe works too.

Robert Boros
  • 48
  • 1
  • 7