標籤:
一篇關於Asp.Net Web Api下載檔案的文章,之前我也寫過類似的文章,請見:《ASP.NET(C#) Web Api通過檔案流下載檔案到本地執行個體》
本文以這篇文章的基礎,提供了ByteArrayContent的下載以及在下載多個檔案時實現在伺服器對多檔案進行壓縮打包後下載的功能。
關於本文中實現的在伺服器端用.NET壓縮打包檔案功能的過程中,使用到了一個第方類庫:DotNetZip,具體的使用將在本文中涉及。好了,描述了這麼多前言,下面我們進入本文樣本的本文。
一、建立項目
1.1 首先建立名為:WebApiDownload的Web Api 項目(C#);
1.2 接著建立一個空的控制器,命名為:DownloadController;
1.3 建立一些打包檔案和存放臨時檔案的檔案夾(downloads),具體請看本文最後提供的樣本項目代碼
1.4 開啟NuGet程式包管事器,搜尋DotNetZip,如:
搜尋到DotNetZip安裝包後,進行安裝,以便用於本項目將要實現多檔案打包壓縮的功能,如:
安裝完成DotNetZip包後,我們就可以退出NuGet封裝管理員了,因為本項目為樣本項目,不需再添加其他的包。
1.5 在Models檔案夾下建立一個樣本資料的類,名為:DemoData,其中的成員和實現如下:
using System.Collections.Generic;namespace WebApiDownload.Models{ public class DemoData { public static readonly List<List<string>> Contacts = new List<List<string>>(); public static readonly List<string> File1 = new List<string> { "[email protected]", "[email protected]", "[email protected]", "[email protected]", "[email protected]" }; public static readonly List<string> File2 = new List<string> { "[email protected]", "[email protected]", "[email protected]", "[email protected]", "[email protected]" }; public static readonly List<string> File3 = new List<string> { "[email protected]", "[email protected]", "[email protected]", "[email protected]", "[email protected]" }; public static List<List<string>> GetMultiple { get { if (Contacts.Count <= 0) { Contacts.Add(File1); Contacts.Add(File2); Contacts.Add(File3); } return Contacts; } } }}
View Code
1.6 到這裡,我們的準備工作基本做得差不多了,最後我們只需要在DownloadController控制器中實現兩個Action,一個為:DownloadSingle(提供下載單個檔案的功能),另一個為:DownloadZip(提供打包壓縮多個檔案並下載的功能)。具體的DownloadController完整代碼如下:
using System.Linq;using System.Net.Http;using System.Text;using System.Web.Http;using Ionic.Zip;using WebApiDownload.Models;using System;using System.IO;using System.Net;using System.Net.Http.Headers;using System.Threading;using System.Web;namespace WebApiDownload.Controllers{ [RoutePrefix("download")] public class DownloadController : ApiController { [HttpGet, Route("single")] public HttpResponseMessage DownloadSingle() { var response = new HttpResponseMessage(); //從List集合中擷取byte[] var bytes = DemoData.File1.Select(x => x + "\n").SelectMany(x => Encoding.UTF8.GetBytes(x)).ToArray(); try { var fileName = string.Format("download_single_{0}.txt", DateTime.Now.ToString("yyyyMMddHHmmss")); var content = new ByteArrayContent(bytes); response.Content = content; response.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment") { FileName = fileName }; response.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream"); } catch (Exception ex) { response.StatusCode = HttpStatusCode.InternalServerError; response.Content = new StringContent(ex.ToString()); } return response; } [HttpGet, Route("zip")] public HttpResponseMessage DownloadZip() { var response = new HttpResponseMessage(); try { var zipFileName = string.Format("download_compressed_{0}.zip", DateTime.Now.ToString("yyyyMMddHHmmss")); var downloadDir = HttpContext.Current.Server.MapPath($"~/downloads/download"); var archive = $"{downloadDir}/{zipFileName}"; var temp = HttpContext.Current.Server.MapPath("~/downloads/temp"); // 清空臨時檔案夾中的所有臨時檔案 Directory.EnumerateFiles(temp).ToList().ForEach(File.Delete); ClearDownloadDirectory(downloadDir); // 產生新的臨時檔案 var counter = 1; foreach (var c in DemoData.GetMultiple) { var fileName = string.Format("each_file_{0}_{1}.txt", counter, DateTime.Now.ToString("yyyyMMddHHmmss")); if (c.Count <= 0) { continue; } var docPath = string.Format("{0}/{1}", temp, fileName); File.WriteAllLines(docPath, c, Encoding.UTF8); counter++; } Thread.Sleep(500); using (var zip = new ZipFile()) { // Make zip file zip.AddDirectory(temp); zip.Save(archive); } response.Content = new StreamContent(new FileStream(archive, FileMode.Open, FileAccess.Read)); response.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment") { FileName = zipFileName }; response.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream"); } catch (Exception ex) { response.StatusCode = HttpStatusCode.InternalServerError; response.Content = new StringContent(ex.ToString()); } return response; } private void ClearDownloadDirectory(string directory) { var files = Directory.GetFiles(directory); foreach (var file in files) { try { File.Delete(file); } catch { } } } }}
View Code二、運行樣本
2.1 到此,本樣本的實現代碼部分就完成了,如果我們此時開啟地址:http://localhost:63161/download/single,瀏覽器會彈出儲存檔案的提示視窗,如下:
2.2 儲存此檔案後,開啟它我們會看到我們的樣本資料已被儲存到本地了,如下:
文章:Asp.Net Web Api 2利用ByteArrayContent和StreamContent分別實現下載檔案樣本源碼(含多檔案壓縮功能)
Asp.Net Web Api 2 實現多檔案打包並下載檔案樣本源碼_轉