问题:从ASP.NET Core MVC控制器返回文件时,文件未下载。

huangapple go评论116阅读模式
英文:

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

问题

我正在尝试创建一个在浏览器中启动文件下载的“下载”按钮。

以下是我的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);
}

这段代码应该从数据库中获取数据,并创建一个CSV文件以供下载,但我已经简化了代码。

在视图中,我有一个按钮,使用Knockout进行数据绑定:

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

以及我的viewModel中的代码:

downloadAnswers(batchId: number) {
    Q($.ajax({
        url: `/Attestering/AdminTools/${batchId}/DownloadAnswers/`,
        type: 'GET'
    }));
}

当我点击按钮时,我得到以下响应:

请求头:

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"

响应头:

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

响应体:

Hello World!

但我没有收到文件下载。我已经尝试了许多不同的方法,主要在控制器部分。有没有提示?

英文:

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

Here is my Controller:

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

        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

 &lt;button class=&quot;btn btn-light&quot; data-bind=&quot;click: () =&gt; $parent.downloadAnswers(line.BatchId)&quot;&gt;&lt;i class=&quot;fad fa-file-download fa-fw&quot;&gt;&lt;/i&gt; Download &lt;/button&gt;

and the code in my viewModel

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

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

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: &quot;Chromium&quot;;v=&quot;110&quot;, &quot;Not A(Brand&quot;;v=&quot;24&quot;, &quot;Google Chrome&quot;;v=&quot;110&quot;
sec-ch-ua-mobile: ?0
sec-ch-ua-platform: &quot;Windows&quot;

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&#39;&#39;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 ?

答案1

得分: 0

你的控制器部分是正常的,如果你可以通过MimeHelper.GetMimeMapping(fileName)获取正确的内容类型,但由于你尝试使用ajax调用,所以失败了,你会在ajax调用的响应中获取文件内容(例如作为字符串),而不是文件。

我尝试了两种解决方案,希望能帮助你:

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

控制器部分:

[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);
}

结果:

问题:从ASP.NET Core MVC控制器返回文件时,文件未下载。

英文:

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:

&lt;input type=&quot;button&quot; onclick=&quot;downloadtxt()&quot; value=&quot;DownloadTxt&quot;/&gt;

&lt;input type=&quot;button&quot; onclick=&quot;downloadcsv()&quot; value=&quot;DownloadCSV&quot;/&gt;



&lt;script&gt;
    function downloadtxt(){
        window.open(&quot;/Home/DownloadTxt&quot;)        
    }

    function downloadcsv(){
       var eleForm = $(&quot;&lt;form method=&#39;get&#39;&gt;&lt;/form&gt;&quot;);
       eleForm.attr(&quot;action&quot;,&quot;/Home/DownloadCsv&quot;);
       $(document.body).append(eleForm);
       eleForm.submit();
    }
&lt;/script&gt;

Controller:

[HttpGet]
        public async Task&lt;FileResult&gt; DownloadTxT( )
        {
            string fileName = &quot;test.txt&quot;;
            byte[] filebytes = Encoding.UTF8.GetBytes(&quot;Hello World!&quot;);

            return File(filebytes, &quot;text/plain&quot;, fileName);
        }

        [HttpGet]
        public async Task&lt;FileResult&gt; DownloadCSV()
        {
            string fileName = &quot;test.csv&quot;;
            byte[] filebytes = Encoding.UTF8.GetBytes(&quot;Hello World!&quot;);

            return File(filebytes, &quot;text/csv&quot;, fileName);
        }

Result:

问题:从ASP.NET Core MVC控制器返回文件时,文件未下载。

huangapple
  • 本文由 发表于 2023年3月7日 21:57:32
  • 转载请务必保留本文链接:https://go.coder-hub.com/75662931.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定