Search code examples
c#downloadasp.net-core-mvchttpresponse

Problem Returning file from ASP.NET Core MVC Controller- File is not downloaded


I'm trying to build a "download" button that starts a file download in the browser.

Here is my Controller:

    [HttpGet("AdminTools/{batchId}/DownloadAnswers")]
    public async Task<FileResult> DownloadAnswers(int batchId)
    {
        string fileName = "test.txt";
        byte[] filebytes = Encoding.UTF8.GetBytes("Hello World!");

        return File(filebytes, MimeHelper.GetMimeMapping(fileName), fileName);
    }

It is supposed to grab data from a database, and create a CSV file for delivery, but i've slimmed down the code.

In the view i have this button using knockout to data-bind click

 <button class="btn btn-light" data-bind="click: () => $parent.downloadAnswers(line.BatchId)"><i class="fad fa-file-download fa-fw"></i> Download </button>

and the code in my viewModel

 downloadAnswers(batchId: number) {
        Q($.ajax({

            url: `/Attestering/AdminTools/${batchId}/DownloadAnswers/`,
            type: 'GET'
        }));
    }

When I click the button I get this response:

Request headers:
GET /Attestering/AdminTools/91/DownloadAnswers/ HTTP/1.1
Accept: */*
Accept-Encoding: gzip, deflate, br
Accept-Language: da-DK,da;q=0.9,en-US;q=0.8,en;q=0.7
Cache-Control: no-cache
Connection: keep-alive
Cookie: .AspNetCore.Antiforgery.QdXrCqqGsrk=CfDJ8KXm89uE_DNAripaOM8IAxzND7VK_PQPxpfmXtgTsKY1uN3acIgiucBdlkKaXs_eJvQu2Te066RjYnOlazo2P1oKclowja9hkxKhzrwIzq8GHhmsAhA_ZLQbMoFg59FeSEfExF04U6KJYk0W-Whhb1A
Host: localhost:7777
Pragma: no-cache
Referer: https://localhost:7777/attestering/admintools
Sec-Fetch-Dest: empty
Sec-Fetch-Mode: cors
Sec-Fetch-Site: same-origin
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/110.0.0.0 Safari/537.36
X-Requested-With: XMLHttpRequest
sec-ch-ua: "Chromium";v="110", "Not A(Brand";v="24", "Google Chrome";v="110"
sec-ch-ua-mobile: ?0
sec-ch-ua-platform: "Windows"

And this Reponse header:

HTTP/1.1 200 OK
Content-Length: 12
Content-Type: text/plain
Date: Tue, 07 Mar 2023 13:34:44 GMT
Server: Kestrel
Content-Disposition: attachment; filename=test.txt; filename*=UTF-8''test.txt

And this Reponse

Hello World!

But I don't get the file download.

I've been searching and trying many different things. Mostly on the controller side.

Any hints ?


Solution

  • Your controller side is OK,if you could get the correct content-type with MimeHelper.GetMimeMapping(fileName), you failed just because you tried with an ajax call,you would get the content of the file (for example as string) in resopnse of ajax call instead of the file

    I tried with the two solutions,hopes could help:

    <input type="button" onclick="downloadtxt()" value="DownloadTxt"/>
    
    <input type="button" onclick="downloadcsv()" value="DownloadCSV"/>
    
    
    
    <script>
        function downloadtxt(){
            window.open("/Home/DownloadTxt")        
        }
    
        function downloadcsv(){
           var eleForm = $("<form method='get'></form>");
           eleForm.attr("action","/Home/DownloadCsv");
           $(document.body).append(eleForm);
           eleForm.submit();
        }
    </script>
    

    Controller:

    [HttpGet]
            public async Task<FileResult> DownloadTxT( )
            {
                string fileName = "test.txt";
                byte[] filebytes = Encoding.UTF8.GetBytes("Hello World!");
    
                return File(filebytes, "text/plain", fileName);
            }
    
            [HttpGet]
            public async Task<FileResult> DownloadCSV()
            {
                string fileName = "test.csv";
                byte[] filebytes = Encoding.UTF8.GetBytes("Hello World!");
    
                return File(filebytes, "text/csv", fileName);
            }
    

    Result:

    enter image description here