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 ?
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: