Base solution for your next web application
Open Closed

Trying to download file in the browser from database. #6669


User avatar
0
system15 created

I am trying to download the file by id using this method but all it is doing is returning the HttpResponse in json format in swagger but what I'm trying to achieve is the file being download in the browser. Does anyone know what is needed to be done to get the correct outcome?

I have a FileUpload table that has the following columns (related to the file): Id = uniqueidentifier, Content = varbinary, ContentType = nvarchar, e.g. application/pdf FileName = nvarchar, e.g. filename.pdf FileType = tinyint e.g.

`Here is the method in the Project.Application

    /// <summary>
    /// Download the file from the database by id.
    /// </summary>
    /// <param name="id">The identifier.</param>
    /// <returns>The file.</returns>
    public async Task<HttpResponseMessage> GetDownloadFile(Guid id)
    {
        HttpResponseMessage result = new HttpResponseMessage(HttpStatusCode.OK);
        var file = await _fileUploadRepository.FirstOrDefaultAsync(id);
        var filename = file.FileName.ToString();
        var ms = new MemoryStream(file.Content);
        ms.Position = 0;
        result.Content = new StreamContent(ms);
        result.Content.Headers.ContentType = new MediaTypeHeaderValue(file.ContentType);
        result.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment")
        {
            FileName = Uri.EscapeDataString(file.FileName)
        };

        return result;
    }

`

`Here is the typescript in Web.Host

/// <summary> 
/// Download the file from the database by id.
/// </summary>
///<param name="id">The identifier.</param>
downloadFile(id: string, event) {
    if (id) {
        debugger;//Todo: remove.

        this._fileUploadsServiceProxy.downloadFile(id)
            .subscribe(result => {
                this.notify.success(`Downloaded successfully.`);
            });
    }
}

`


8 Answer(s)
  • User Avatar
    0
    ryancyq created
    Support Team

    Hi, is this file download method located in application service?

    You could try adding DontWrapResult attribute to the method.

  • User Avatar
    0
    system15 created

    Thanks @ryancyq I have added the WrapResult to the method and tested the method using swagger api and inserted a file id from the database but it still doesn't download the file:

    `Here is the code:

        /// <summary>
        /// Download the file from the database by id.
        /// </summary>
        /// <param name="id">The identifier.</param>
        /// <returns>The file.</returns>
        [WrapResult(WrapOnSuccess = false, WrapOnError = false)]
        public async Task<HttpResponseMessage> GetDownloadFile(Guid id)
        {
            HttpResponseMessage result = new HttpResponseMessage(HttpStatusCode.OK);
            var file = await _fileUploadRepository.FirstOrDefaultAsync(id);
            var filename = file.FileName.ToString();
            var ms = new MemoryStream(file.Content);
            ms.Position = 0;
            result.Content = new StreamContent(ms);
            result.Content.Headers.ContentType = new MediaTypeHeaderValue(file.ContentType);
            result.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment")
            {
                FileName = Uri.EscapeDataString(file.FileName)
            };
    
            return result;
        }
    

    `

  • User Avatar
    0
    ismcagdas created
    Support Team

    Hi @system15

    Could you use Controller instead of AppService ?

  • User Avatar
    0
    system15 created

    I'll add the method to the controller in Web.Core.

    Following the example in DemoUiComponentsController.cs @ismcagdas is there an example of how to pass parameters to the controller method as the UploadFiles method is different.

  • User Avatar
    0
    ryancyq created
    Support Team

    Hi @system15,

    You can take reference from profile related controller for file upload/download in your case.

    See https://github.com/aspnetzero/aspnet-zero-core/blob/4180b6eccb0c02e14a17d1e383ed3906f6174cdd/aspnet-core/src/MyCompanyName.AbpZeroTemplate.Web.Core/Controllers/FileController.cs

    and https://github.com/aspnetzero/aspnet-zero-core/blob/8672111621dffd72f96a2e4f8670d9584568b29a/aspnet-core/src/MyCompanyName.AbpZeroTemplate.Web.Core/Controllers/ProfileControllerBase.cs

  • User Avatar
    0
    system15 created

    Ok I still can't download a file from the database but it never hits the controller any ideas where I'm going wrong?

    This is the typescript function that gets called on click (I only included relevant code):

       import { Http, Response, Headers, RequestOptions } from '@angular/http';
       
       constructor(
            injector: Injector,
            private _fileUploadsServiceProxy: FileUploadsServiceProxy,
            private _notifyService: NotifyService,
            private _tokenAuth: TokenAuthServiceProxy,
            private _activatedRoute: ActivatedRoute,
            private _fileDownloadService: FileDownloadService,
            private _searchService: SearchService,
            private http: Http
        ) {
            super(injector);
        }
       
        downloadFile(id: string): any {
            var headers = new Headers();
            headers.append('Content-Type', 'application/octetstream');
            headers.append('Authorization', 'Bearer ' + abp.auth.getToken());
            return this.http.get(`${AppConsts.remoteServiceBaseUrl}/FileUploadComponents/DownloadFile?id= ${id}`); 
        }
    

    This is the FileUploadComponentsController.cs

            [HttpGet]
            public async Task<ActionResult> GetDownloadFile(Guid id)
            {
                if (id == null)
                {
                    throw new UserFriendlyException("File not found.");
                }
                var file = await _fileUploadRepository.FirstOrDefaultAsync(id);
                var filename = file.FileName.ToString();
                var fileBytes = file.Content;
                return File(fileBytes, file.ContentType,file.FileName);
            }
    
  • User Avatar
    0
    peabmw created

    I just posted a similar question on download which might help you out a bit: https://support.aspnetzero.com/QA/Questions/6699

    Download works but I have the issue of not being able to set Authorization header.

  • User Avatar
    0
    ismcagdas created
    Support Team