Open Closed

How to get filename in angular side when we call file download api. #1055


User avatar
0
kaustubh.kale@ness.com created

Check the docs before asking a question: https://docs.abp.io/en/commercial/latest/ Check the samples, to see the basic tasks: https://docs.abp.io/en/commercial/latest/samples/index The exact solution to your question may have been answered before, please use the search on the homepage.

ABP Framework version: v3.0.4 UI type: Angular DB provider: EF Core Tiered (MVC) or Identity Server Seperated (Angular): no / yes Exception message and stack trace: Steps to reproduce the issue:

Issue: when we are calling api from angular side we are not able to get filename of that blob file. How to get filename with filetype in angular side when we call api. below are angular and .net code for file download implementation.

download file api code:

Angular api call implementation :

selectedInvoicesToExcelDownloadByInput(body: any): Observable<any> { let url = ${this.apiUrl.url}/api/InvoiceManagement/AR/invoice/selectedInvoicesToExcelDownload return this.http.post(url, body, { responseType: 'blob' ,observe: 'response' }) }

.net api code

[HttpPost]
    [Route("disputedInvoicesToExcelDownload")]
    public async Task&lt;IActionResult&gt; DisputedInvoicesToExcelDownload(ARDisputedInvoicesUploadDto input)
    {
        var fileDto = await _invoiceAppService.DisputedInvoicesToExcelAsync(input);
        return File(fileDto.Content, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", fileDto.Name);
    }

8 Answer(s)
  • User Avatar
    0
    cotur created

    Hi @kaustubh.kale@ness.com

    If you are using directly the Abp Blob storage, you should create a table that you will store the blob name & type. Then you can use the database entity that related with blob.

  • User Avatar
    0
    lalitChougule created

    Hi,

    This is the angular service code as below :

    selectedInvoicesToExcelDownloadByInput(body: any): Observable<any> {
        let url = `${this.apiUrl.url}/api/InvoiceManagement/AR/invoice/selectedInvoicesToExcelDownload`
        return this.http.post(url, body, {
          responseType: 'blob'
        })
      }
    

    Thie is the method where service method is called, code as below :

    this.Invoiceservice.selectedInvoicesToExcelDownloadByInput(program).subscribe((res) => {
              var blob = new Blob([res], { type: res.type.toString() });
             var url = window.URL.createObjectURL(blob);
             var anchor = document.createElement("a");
             anchor.download = this.fileformatName();
             anchor.href = url;
             anchor.click();
            });
    

    What I need is to get access of the below marked blue rectangle :


    How do I access this ? If I go with normal approach of state as per document I get parsing error where I cant prase my returned blob to excel file. The only way I was able to generate excel file is by implementation done above, but now I cannot access the name of the file.

    Code sample will help alot !!!

  • User Avatar
    0
    bunyamin created

    Hello,

    If you simply pass observe: 'response' to the RestService, it will return the whole response object which includes headers.

      selectedInvoicesToExcelDownloadByInput(body: any): Observable<any> {
        let url = `${this.apiUrl.url}/api/InvoiceManagement/AR/invoice/selectedInvoicesToExcelDownload`
        return this.http.post(url, body, {
          responseType: 'blob',
          observe: 'response' // simply add this option
        })
      }
    
  • User Avatar
    0
    lalitChougule created

    Hi @bunyamin,

    I tried this observe: 'response' but I was getting header as null, Is there any other way ? Cause as I said before If I try abp.io rest service then I am getting json parsing error and if I try by angular http approach I am able download the file but I am not able to get access of Content-Disposition where I am getting name of the file. Please check my code above once for your reference.

  • User Avatar
    0
    bunyamin created

    Hello again,

    If you want to read some headers from the response of a cross origin request, the backend has to return those header names in Access-Control-Expose-Headers. ABP Framework already adds its own _AbpErrorFormat. You just need to expand this and add whatever you need.

    You need to expose the header Content-Disposition from where cors is configured.

    private void ConfigureCors(ServiceConfigurationContext context, IConfiguration configuration)
    {
        context.Services.AddCors(options =>
        {
            options.AddPolicy(DefaultCorsPolicyName, builder =>
            {
                builder
                    .WithOrigins(
                        // ...
                    )
                    .WithAbpExposedHeaders()
                    .WithExposedHeaders("Content-Disposition") // <- Add this line
                    // ...
                    ;
            });
        });
    }
    

    Now, you can simply read headers from the client. Don't forget to pass observe: Rest.Observe.Response to the RestService

      selectedInvoicesToExcelDownloadByInput(body: any): Observable<any> {
        return this.restService.request<any, any>(
          {
            method: 'GET',
            url: `/api/InvoiceManagement/AR/invoice/selectedInvoicesToExcelDownload`,
            responseType: 'blob',
          } as any,
          { 
            apiName: this.apiName, 
            observe: Rest.Observe.Response 
          }
        )
      }
      
      this.Invoiceservice.selectedInvoicesToExcelDownloadByInput(program).subscribe((res) => {
         console.log(res.headers.get('content-disposition')); // <- will log "attachment;filename="test.txt""
      })
    
  • User Avatar
    0
    kaustubh.kale@ness.com created

    Hi @bunyamin

    We did the above mentioned changes in our code so we are getting 415 unsupported media type error in our request call.

    Only differance is our method call is POST.

  • User Avatar
    0
    bunyamin created

    Hi,

    You used to be able to make your request call before. What I suggested was a configuration for CORS. It should not have anything to do with "415 unsupported media type". Change your code back to what it was (when you could make the call but could not read the headers) and add .WithExposedHeaders("Content-Disposition"). When everything is done correctly, you should see the following among the response headers:

    Access-Control-Expose-Headers: _AbpErrorFormat, Content-Disposition

  • User Avatar
    0
    ServiceBot created
    Support Team Automatic process manager

    This question has been automatically marked as stale because it has not had recent activity.

Made with ❤️ on ABP v8.2.0-preview Updated on March 25, 2024, 15:11