日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > asp.net >内容正文

asp.net

ASP.NET CORE WEBAPI文件下载

發布時間:2023/12/4 asp.net 24 豆豆
生活随笔 收集整理的這篇文章主要介紹了 ASP.NET CORE WEBAPI文件下载 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

最近要使用ASP.NET CORE WEBAPI用來下載文件,使用的.NET CORE 3.1。考慮如下場景:

  • 文件是程序生成的。

  • 文件應該能兼容各種格式。

  • 瀏覽器可以感知進行下載。

  • 準備

    經過簡單的調研,得到以下結論。

    • ASP.NET CORE 提供FileResult這種類型的ActionResult,可以直接返回文件結果,不需要直接處理HttpResponse。

    • 通過Stream可以直接返回文件流供瀏覽器下載。

    • FileStreamResult是FileResult的具體實現,返回值應該是此類對象。

    • Stream有多種類型,適合直接內存中生成文件對象的是MemoryStream。
      對目標有了基礎的了解,就可以開始動手實現了。

    實現

    建立好ASP.NET CORE WEBAPI工程,把生成文件的代碼獨立出來一個函數。我這里需要是下載一個CSV格式的文件,因此生成一個CSV文件。
    對于磁盤上的文件,可以使用FileStream對象,由于我這里需要運行中生成這個文件,需要使用MemoryStream。

    using var stream = new MemoryStream(); using var writer = new StreamWriter(stream); //生成標題 var propCollection = ttype.GetProperties(); foreach (var n in propCollection) {writer.Write(n.Name);writer.Write(","); } writer.WriteLine(); //生成內容 foreach (var item in res) {foreach (var n in propCollection){writer.Write(Convert.ToString(n.GetValue(item)));writer.Write(",");}writer.WriteLine(); }
  • 請不要考慮里面反射的相關內容,按照自己的邏輯生成CSV即可,我只是懶得改代碼而已。

  • 代碼中使用到了一些新的語法特性,請注意對低版本的.NET不一定適用。
    直接返回Stream對象給Controller處理,處理代碼如下:

  • var res = await info.GetAllQueryResult(); var actionresult = new FileStreamResult(res, new Microsoft.Net.Http.Headers.MediaTypeHeaderValue("text/csv")); return actionresult;

    CSV的Content-Type是text/csv,如果下載別的文件,請自行查詢MIME格式。

    調試

    直接執行上面的代碼,直接報錯“無法讀取已經關閉的流”。猜測是離開using語句塊的時候,stream自動被關閉了。改動很簡單,去掉using語句,不再報相同錯誤。

    但是返回的文件長度一直是0,單步調試發現Writer執行完畢之后,stream返回的長度是0,內容實際上并沒有寫入,想起有一個Flush(),可以添加以確保數據寫入。

    單步顯示stream長度有了,但是返回的長度還是0。繼續單步調試發現Stream的Postion是停在文件結尾的,這個和直接開始讀取文件完全不一樣,文件讀取一般是從開頭開始的,于是直接設置Postion為0,問題解決。

    下載能夠成功了,但是文件名一直顯示的是隨機生成的,體驗很差。設置一下FileDownloadName即可。

    核心代碼如下:

    public async Task<Stream> GetAllQueryResult() {var stream = new MemoryStream();var writer = new StreamWriter(stream);//生成標題var propCollection = ttype.GetProperties();foreach (var n in propCollection){writer.Write(n.Name);writer.Write(",");}writer.WriteLine();//生成內容foreach (var item in res){foreach (var n in propCollection){writer.Write(Convert.ToString(n.GetValue(item)));writer.Write(",");}writer.WriteLine();}writer.Flush();stream.Position = 0;return stream; } [HttpPost("file")] [ProducesResponseType(typeof(FileResult), Status200OK)] public async Task<FileResult> Download() {var info = new Info();var res = await info.GetAllQueryResult();var actionresult = new FileStreamResult(res, new Microsoft.Net.Http.Headers.MediaTypeHeaderValue("text/csv"));actionresult.FileDownloadName = "Carinfos.csv";//Response.ContentLength = res.Length;return actionresult; }

    使用swagger調用,最后效果:

    總結

    后來查了一些資料,總結了一下:

    • MemoryStream如果使用using語句,會在離開代碼塊的時候自動關閉,實際上ASP.NET CORE會自動處理關閉的事項,不需要使用using語句。

    • 由于生成文件的過程是從文件流的開頭一直進行到末尾的,因此向請求端返回結果時,應當重置Stream的游標,從0開始傳輸。

    • 記得在使用writer之后使用Flush()以確保數據有寫入。

    • 如果不確定文件格式,可以直接返回MIME值為application/oct-stream。

    • 設置FileStreamResult的FileDownloadName屬性可以修改文件的默認名稱。

    • (可選)可以通過設置Response.ContentLength來設置文件的長度。

    參考資料:

    https://darchuk.net/2019/05/31/asp-net-core-web-api-returning-a-filestream/

    總結

    以上是生活随笔為你收集整理的ASP.NET CORE WEBAPI文件下载的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。