Reputation: 12709
I'm trying to download a file from the server but the file is not displaying it's original content instead it's displaying [object Object].
WEB API CORE
[Authorize(AuthenticationSchemes = "Bearer")]
[HttpGet]
public HttpResponseMessage DownloadContractFile(string fileName)
{
string contentRootPath = _hostingEnvironment.ContentRootPath;
var folderName = Path.Combine(contentRootPath, FileHandler.ContractFilePath, Convert.ToInt32(User.Identity.Name).ToString());
var path = Path.Combine(folderName, fileName);
var memory = new MemoryStream();
HttpResponseMessage result = new HttpResponseMessage(HttpStatusCode.OK);
using (var stream = new FileStream(path, FileMode.Open))
{
result.Content = new StreamContent(stream);
result.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment");
result.Content.Headers.ContentDisposition.FileName = Path.GetFileName(path);
result.Content.Headers.ContentType = new MediaTypeHeaderValue(FileHandler.GetContentType(path)); // Text file
result.Content.Headers.ContentLength = stream.Length;
return result;
}
}
Angular Code: Service method
downloadContractFile(fileName: string) {
const obj: any = { fileName: fileName };
const httpParams: HttpParamsOptions = { fromObject: obj } as HttpParamsOptions;
const httpOptions = {
params: new HttpParams(httpParams),
headers: new HttpHeaders({
'Content-Type': 'application/octet-stream',
'Authorization': 'Bearer ' + this.jwt.getToken
})
};
return this.http.get<Array<any>>(`${this.settings.getApiSettings('uri')}/api/contract/DownloadContractFile`, httpOptions).map( /// <<<=== use `map` here
(response) => {
if (response["status"] == 401) {
this.jwt.redirectToLogin();
}
else if (response["status"] < 200 || response["status"] >= 300) {
throw new Error('This request has failed ' + response["status"]);
}
let data = response;
return data;
}
);
}
Component.ts
downloadFile(fileName) {
this.js.checkTokenValid().subscribe(res => {
if (res == null)
this.js.redirectToLogin();
else {
this.conc.downloadContractFile(fileName).subscribe(respData => {
console.log(respData);
this.type = respData.content["headers"][1]["value"][0];
this.downFile(respData.content, this.type, fileName);
}, error => {
});
}
});
}
downFile(data: any, type: string, fileName: string) {
var blob = new Blob([data], { type: type });
var url = window.URL.createObjectURL(blob);
saveAs(blob, fileName);
//var fileURL = URL.createObjectURL(res);
//window.open(fileURL); // if you want to open it in new tab
}
Component.html
<a href="javascript:void(0)" (click)="downloadFile(item.fileName);">download file</a>
Response Received
Received file content
Upvotes: 3
Views: 13547
Reputation:
This is my code which I using in the project to download the file.
Controller Code :
[HttpGet("DownloadFile")]
public async Task<IActionResult> DownloadFile(string fileName = "")
{
var response = await DownloadFileFromDatabase(fileName);
if (response.IsSuccessStatusCode)
{
System.Net.Http.HttpContent content = response.Content;
var contentStream = await content.ReadAsStreamAsync();
var audioArray = ReadFully(contentStream);
return Ok(new { response = audioArray, contentType = "audio/wav", fileName });
}
else
{
throw new FileNotFoundException();
}
}
Client Side Code:
HandleBase64 (data , contentType,fileName ){
let byteCharacters = atob(data);
let byteNumbers = new Array(byteCharacters.length);
for (var i = 0; i < byteCharacters.length; i++)
byteNumbers[i] = byteCharacters.charCodeAt(i);
let byteArray = new Uint8Array(byteNumbers);
let blob = new Blob([byteArray], {type: contentType});
if(contentType === "audio/wav"){
var blobURL=URL.createObjectURL(blob);
window.open(blobURL);
}
else{
var blobURL = window.URL.createObjectURL(blob);
var anchor = document.createElement("a");
anchor.download = fileName;
anchor.href = blobURL;
anchor.click();
}
}
You can also simply return file using file stream in the controller side. This will automatically download the file no need to handle in client side
return File(stream, "application/octet-stream");
Upvotes: 5