Hello @musa.demir
I have the below method. The problem is that when I execute the download method it takes a long time to actually see the file start downloading on my screen. After further looking at development tools when executing downloadFile method I see the content in the background transferring as seen below.
once the transfer is complete the code under subscribe executes and I can see the actual file downloading as below
Please advise. I haven't been able to figure how to skip the transfer content as it seems redudant to perform the content transfer and the download.
downlodFile(id): void {
let filedownloadInput = new FileDownloadInput();
filedownloadInput.id = id;
this._FileManagerService.downloadFile(filedownloadInput).subscribe(item => {
this.InitializeDownload(item.fileName, item.fileToken).subscribe((data: any) => {
this.blob = new Blob([data], { type: 'application/pdf' });
var downloadURL = window.URL.createObjectURL(data);
var link = document.createElement('a');
link.href = downloadURL;
link.download = item.fileName;
link.click();
});
});
} InitializeDownload(fileName:string, fileToken:string) { const url = AppConsts.remoteServiceBaseUrl + '/FileManager/GetFile'; this.token = this._tokenService.getToken(); let params = new HttpParams();
params = params.append('fileName', fileName);
params = params.append('fileToken', fileToken);
const httpOptions = {
responseType: 'blob' as 'json',
headers: new HttpHeaders({
"Authorization": "Bearer " + this.token
}),
params: params
};
return this._httpClient.get(url, httpOptions);
}
this was generated with the refresh.bat command.
/**
* @param body (optional)
* @return Success
*/
downloadFile(body: FileDownloadInput | undefined): Observable<FileDownloadOutput> {
let url_ = this.baseUrl + "/api/services/app/FileManager/DownloadFile";
url_ = url_.replace(/[?&]$/, "");
const content_ = JSON.stringify(body);
let options_ : any = {
body: content_,
observe: "response",
responseType: "blob",
headers: new HttpHeaders({
"Content-Type": "application/json-patch+json",
"Accept": "text/plain"
})
};
return this.http.request("post", url_, options_).pipe(_observableMergeMap((response_ : any) => {
return this.processDownloadFile(response_);
})).pipe(_observableCatch((response_: any) => {
if (response_ instanceof HttpResponseBase) {
try {
return this.processDownloadFile(<any>response_);
} catch (e) {
return <Observable<FileDownloadOutput>><any>_observableThrow(e);
}
} else
return <Observable<FileDownloadOutput>><any>_observableThrow(response_);
}));
}
protected processDownloadFile(response: HttpResponseBase): Observable<FileDownloadOutput> {
const status = response.status;
const responseBlob =
response instanceof HttpResponse ? response.body :
(<any>response).error instanceof Blob ? (<any>response).error : undefined;
let _headers: any = {}; if (response.headers) { for (let key of response.headers.keys()) { _headers[key] = response.headers.get(key); }};
if (status === 200) {
return blobToText(responseBlob).pipe(_observableMergeMap(_responseText => {
let result200: any = null;
let resultData200 = _responseText === "" ? null : JSON.parse(_responseText, this.jsonParseReviver);
result200 = FileDownloadOutput.fromJS(resultData200);
return _observableOf(result200);
}));
} else if (status !== 200 && status !== 204) {
return blobToText(responseBlob).pipe(_observableMergeMap(_responseText => {
return throwException("An unexpected server error occurred.", status, _responseText, _headers);
}));
}
return _observableOf<FileDownloadOutput>(<any>null);
}
public async Task<FileDownloadOutput> DownloadFile(FileDownloadInput input)
{
var fileInfo = await _filesObjectsRepository.FirstOrDefaultAsync(c => c.Id == input.Id);
var output = new FileDownloadOutput()
{
FileName = fileInfo.FileName,
FileToken = fileInfo.Identifier
};
return output;
}
I no longer get the kestreI error but still get the same result. I can see the content download on dev tools (zone.js as XHR) then once transfer is complete the download starts.
On the angular side I have the below code. Once the method subscribes (InitializeDownload()) I can see the download on the developer tools under network once the transfer is done the code under subscribe method executes
when looking at the serve logs
WARN 2020-06-17 09:57:07,055 [23 ] nostics.DeveloperExceptionPageMiddleware - The response has already started, the error page middleware will not be executed. ERROR 2020-06-17 09:57:07,056 [23 ] Microsoft.AspNetCore.Server.Kestrel - Connection id "0HM0IRS3OGV70", Request id "0HM0IRS3OGV70:00000035": An unhandled exception was thrown by the application.
Second part of code is the asp.netcore
I can't figure out why it makes two request and why it takes really long for the download to start.
Angular: downlodFile(id): void {
let filedownloadInput = new FileDownloadInput();
filedownloadInput.id = id;
this._FileManagerService.downloadFile(filedownloadInput).subscribe(item => {
this.InitializeDownload(item.fileName, item.fileToken).subscribe((data: any) => {
this.blob = new Blob([data], { type: 'application/pdf' });
var downloadURL = window.URL.createObjectURL(data);
var link = document.createElement('a');
link.href = downloadURL;
link.download = item.fileName;
link.click();
});
});
}
InitializeDownload(fileName:string, fileToken:string) {
const url = AppConsts.remoteServiceBaseUrl + '/FileManager/GetFile';
this.token = this._tokenService.getToken();
let params = new HttpParams();
params = params.append('fileName', fileName);
params = params.append('fileToken', fileToken);
const httpOptions = {
responseType: 'blob' as 'json',
headers: new HttpHeaders({
"Authorization": "Bearer " + this.token
}),
params: params
};
return this._httpClient.get(url, httpOptions);
}
**
necore**
public async Task GetFile( string fileName, string fileToken)
{
Stream stream = null;
int bufferSize = 1048576;
byte[] buffer = new byte[bufferSize];
int length;
long lengthToRead;
try
{
string filePath = Path.Combine(_env.WebRootPath, $"Common{Path.DirectorySeparatorChar}", $"Files{Path.DirectorySeparatorChar}", fileToken);
stream = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read);
long dj = stream.Length / bufferSize;
if (stream.Length % bufferSize > 0)
{
dj += 1;
}
dj = dj * bufferSize;
lengthToRead = stream.Length;
Response.ContentType = "application/pdf";
Response.Headers.Add("Content-Disposition", "attachment; filename=" + fileName);
Response.Headers.Add("content-length", dj.ToString());
// Response.ContentLength = dj;
while( lengthToRead > 0)
{
length = stream.Read(buffer, 0, bufferSize);
await Response.BodyWriter.WriteAsync(buffer);
await Response.BodyWriter.FlushAsync();
lengthToRead = lengthToRead - length;
}
}
catch(Exception exp)
{
Response.ContentType = "text/html";
}
finally
{
if(stream != null)
{
stream.Close();
}
}
}
}
Yes, that worked. I noticed one thing. When I upload a large file it takes a long time before the request is sent to the backend(asp.netcore). what could this be?
Another questions, is it being sent in chunks?
I'm trying to upload a 25GB file using the ng2-file-upload but I'm getting the following error on large files : Access to XMLHttpRequest at 'https://localhost:44301/FileManager/UploadFile' from origin 'http://localhost:4200' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. Smaller files work okay.
upload(): void {
var parentId = document.getElementById('folderId').innerHTML;
this._uploaderOptions.autoUpload = false;
this._uploaderOptions.authToken = 'Bearer ' + this._tokenService.getToken();
this._uploaderOptions.removeAfterUpload = true;
this.uploader.onAfterAddingFile = (file) => {
file.withCredentials = false;
};
this.uploader.onBuildItemForm = (fileItem: FileItem, form: any) => {
form.append('FileType', fileItem.file.type);
form.append('FileName', fileItem.file.name);
form.append('FileToken', this.guid());
form.append('FolderId', parentId);
};
this.uploader.onSuccessItem = (item, response, status) => {
const resp = <IAjaxResponse>JSON.parse(response);
console.log(resp);
if (resp.success) {
this.InsertDocInformation(resp.result.fileToken, resp.result.fileName, parentId);
} else {
this.message.error(resp.error.message);
}
};
this.uploader.setOptions(this._uploaderOptions);
this.uploader.uploadAll();
}
Hello,
Is it possible to have a windows client app running signal R communicate with ASP.NET Zero. I want to be able to send calls to the app and transfer files between both. What are the limitations and recommendations. Appreciate any light you can shed on this issue.
My WAF was creating the CORS policy issue. Disabled CORS on WAF server.