I have a file on the server that I want to send to the client:
[HttpPost]
public IActionResult Test()
{
byte[] bytes = System.IO.File.ReadAllBytes(Path.Combine(FilesFolder, "test.docx"));
return File(bytes, _contentTypeWord);
}
I also tried with
return PhysicalFile(pathUploadFile, "application/vnd.openxmlformats-officedocument.wordprocessingml.document");
At the client I accept using:
private _downloadFile(data: ArrayBuffer, fileName: string, contentType: string) {
var blob = new Blob([data], { type: contentType });
var url = window.URL.createObjectURL(blob);
var link = document.createElement("a");
link.setAttribute("href", url);
link.setAttribute("download", fileName);
link.style.display = "none";
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
}
public test() {
this.http.post("Diplom/Test", { }, {
headers: this.headers(),
}).subscribe(
result => {
this._downloadFile(result.arrayBuffer(), "test.docx", "application/vnd.openxmlformats-officedocument.wordprocessingml.document")
},
error => {
alert("Не удалось отредактировать файл");
console.error(JSON.stringify(error));
})
}
The file that the client receives is corrupt and does not open. The file that is on the server is fine and opens perfectly. The resulting file still does not open, and even weighs 2 times more (on the server 487 KB, and the client has 925 KB).
Angular Download Link You'll use an anchor tag pointing to the file with the href attribute. The download attribute informs the browser that it shouldn't follow the link but rather download the URL target. You can also specify its value in order to set the name of the file being downloaded.
The updated Angular project template provides a convenient starting point for ASP.NET Core apps using Angular and the Angular CLI to implement a rich, client-side user interface (UI). The template is equivalent to creating an ASP.NET Core project to act as an API backend and an Angular CLI project to act as a UI.
This article discuss about uploading files from an Angular application to ASP.NET Core backend. First you need to create an ASP.NET Core Angular project. Once it is done, you need to create an angular component. And then you can modify the backend implementation.
The simplest solution I’ve come up with is this: expose configuration data from ASP.NET Core via an API endpoint, and have Angular make a request to this endpoint during application startup. The endpoint could return whatever makes sense. A simple JSON object will probably suffice in many cases:
In the next section you will learn how to read and save in ASP.NET Core. In ASP.NET Core you can create a controller, and create an action method. In the action method, you can use Request.Form.Files to read the uploaded files with Form Data from Angular client. The above code is using the Request.Form.Files options.
The pattern was more applicable in the AngularJS/ASP.NET MVC (non-Core) days, because AngularJS could be used to create “Silo SPAs” quite easily, and it had no built-in configuration system to speak of. Neither of those things are true with ASP.NET Core and Angular 2+.
You can use a file result and just provide an api link that will return a FileContentResult.
public IActionResult Download(// some parameter)
{
// get the file and convert it into a bytearray
var locatedFile = ....
return new FileContentResult(locatedFile, new
MediaTypeHeaderValue("application/octet"))
{
FileDownloadName = "SomeFileDownloadName.someExtensions"
};
}
Now you only need to provide the link and browser will know how to handle it. No need to do it yourself then.
Edit: I just tested this approach with angular, you need to do the following to download the file when using angulars HttpClient.
First you need to install file-saver via npm.
npm i --save file-saver
Then in your module import and include HttpClientModule
import { HttpClientModule } from '@angular/common/http';
...
@NgModule({
imports: [
HttpClientModule
...
]
...
})
Now go ahead to your service and do the following
import { HttpClient } from '@angular/common/http';
import { saveAs } from 'file-saver';
@Injectable()
export class MyFileService {
public constructor(private http: HttpClient) {}
public downloadFile() {
this.http.get('my-api-url', { responseType: 'blob' }).subscribe(blob => {
saveAs(blob, 'SomeFileDownloadName.someExtensions', {
type: 'text/plain;charset=windows-1252' // --> or whatever you need here
});
});
}
Then blob is handled and a file-save dialog is created.
I do not know why the option specified in the question does not work. But I found a solution, so to say "in another forest". I'm not very versed, so I'll just describe the process of solving the problem. For the beginning I will immediately say that the problem was on the client's side. The method on the server worked correctly from the start. I decided to use another method to download the files "fetch". And came across the next post in the forum. From there I took the following answer
this.httpClient
.fetch(url, {method, body, headers})
.then(response => response.blob())
.then(blob => URL.createObjectURL(blob))
.then(url => {
window.open(url, '_blank');
URL.revokeObjectURL(url);
});
He did not work for me either. I changed it so
fetch(url, {
method: 'POST',
headers: this.headers()
})
.then(response => response.blob())
.then(blob => URL.createObjectURL(blob))
.then(url => {
window.open(url, '_blank');
});
Because of this line nothing happened
URL.revokeObjectURL(url);
This option worked, but with screwed. He saved the file with a strange name and no extension. Then I changed it so.
fetch(url, {
method: 'POST',
headers: this.headers()
})
.then(response => response.blob())
.then(blob => URL.createObjectURL(blob))
.then(url => {
var link = document.createElement("a");
link.setAttribute("href", url);
link.setAttribute("download", "test.docx");
link.style.display = "none";
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
});
And it works! I apologize for the English. I'm using Google translator
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With