Reputation: 597
I have am getting a file from my web.api (.net core) in my Angular 8 application, but I can't get the file name from the server... If I look at the response in Fiddler, then I can see the filename in the response header (Content-Disposition).
I have the following method in my service:
public getAsCsv(taskId: number): Observable<HttpResponse<Blob>> {
return this.httpClient.get<Blob>(`${this.apiBaseUrl}/getAsCsv/${taskId}`, {
observe: 'response',
responseType: 'blob' as 'json'
});
}
In my component I have this code:
public export(taskSmall: TaskSmall) {
this.taskApiService.getAsCsv(taskSmall.id).subscribe((resp: HttpResponse<Blob>) => {
console.log(resp.headers.get('Content-Disposition')); // is writing null in the console
const filename = resp.headers.get('Content-Disposition');
saveAs(resp.body, filename);
});
}
My web api method look like this:
[HttpGet("getAsCsv/{taskId}")]
[Authorize(Roles = RoleConstants.Admin)]
public async Task<IActionResult> GetAsCsv(int taskId)
{
var result = await _mediator.Send(new GetTaskAsCsvCommand(taskId), CancellationToken.None);
byte[] byteArray = Encoding.ASCII.GetBytes(result.Value);
var response = File(byteArray, "application/csv");
response.FileDownloadName = "something.csv";
return response;
}
If I try to get the parameter "Content-Type" from the header it show the right value (application/csv).
What am I doing wrong?
UPDATE Thanks to @Plochie I ended up doing this:
API:
[HttpGet("getAsCsv/{taskId}")]
[Authorize(Roles = RoleConstants.Admin)]
public async Task<IActionResult> GetAsCsv(int taskId)
{
var result = await _mediator.Send(new GetTaskAsCsvCommand(taskId), CancellationToken.None);
byte[] byteArray = Encoding.ASCII.GetBytes(result.Value);
Response.Headers.Add("x-file-name", "something.csv");
Response.Headers.Add("Access-Control-Expose-Headers", "x-file-name");
return File(byteArray, "application/csv"); ;
}
Client:
public export(taskSmall: TaskSmall) {
this.taskApiService.getAsCsv(taskSmall.id).subscribe((resp: HttpResponse<Blob>) => {
saveAs(resp.body, resp.headers.get('x-file-name'));
});
}
Upvotes: 3
Views: 3222
Reputation: 4117
You might have not exposed this header while sending response. Your server needs to send Access-Control-Expose-Headers
header, so that your header is exposed to client.
Here you can expose Content-Disposition
header or create your own custom header x-file-name
with the filename as value and expose this custom header.
Documentation:
https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Expose-Headers
[HttpGet("getAsCsv/{taskId}")]
[Authorize(Roles = RoleConstants.Admin)]
public async Task<IActionResult> GetAsCsv(int taskId)
{
var result = await _mediator.Send(new GetTaskAsCsvCommand(taskId), CancellationToken.None);
byte[] byteArray = Encoding.ASCII.GetBytes(result.Value);
Response.Headers.Add("x-file-name", "something.csv");
Response.Headers.Add("Access-Control-Expose-Headers", "x-file-name");
return File(byteArray, "application/csv", "something.csv"); ;
}
Upvotes: 5