最近由于工作和個人事務,站點也好久沒更新了,但這并不影響我對.NET的熱情。站點的更新工作還是得想辦法抽時間來完成的。
今天利用中午的時間來寫一篇關于Asp.Net Web Api下載文件的文章,之前我也寫過類似的文章,請見:《ASP.NET(C#) Web Api通過文件流下載文件的實例》
本文以這篇文章的基礎,提供了ByteArrayContent的下載以及在下載多個文件時實現(xiàn)在服務器對多文件進行壓縮打包后下載的功能。
關于本文中實現(xiàn)的在服務器端用.NET壓縮打包文件功能的過程中,使用到了一個第方類庫:DotNetZip,具體的使用將在正文中涉及。好了,描述了這么多前言,下面我們進入本文示例的正文。
1.首先創(chuàng)建名為:WebApiDownload的Web Api 項目(C#);
2.接著新建一個空的控制器,命名為:DownloadController;
3.創(chuàng)建一些打包文件和存放臨時文件的文件夾(downloads),具體請看本文最后提供的示例項目代碼
4.打開NuGet程序包管事器,搜索DotNetZip,如下圖:
![](/d/20211017/50d5ca328a0d9c43a6bde267ad6230ab.gif)
搜索到DotNetZip安裝包后,進行安裝,以便用于本項目將要實現(xiàn)多文件打包壓縮的功能,如下圖:
![](/d/20211017/03dd49785f6199be861c2787959e9142.gif)
安裝完成DotNetZip包后,我們就可以退出NuGet程序包管理器了,因為本項目為示例項目,不需再添加其他的包。
5.在Models文件夾下創(chuàng)建一個示例數(shù)據(jù)的類,名為:DemoData,其中的成員和實現(xiàn)如下:
using System.Collections.Generic;
namespace WebApiDownload.Models
{
public class DemoData
{
public static readonly ListListstring>> Contacts = new ListListstring>>();
public static readonly Liststring> File1 = new Liststring>
{
"f_1_test_1@example.com",
"f_1_test_2@example.com",
"f_1_test_3@example.com",
"f_1_test_4@example.com",
"f_1_test_5@example.com"
};
public static readonly Liststring> File2 = new Liststring>
{
"f_2_test_1@example.com",
"f_2_test_2@example.com",
"f_2_test_3@example.com",
"f_2_test_4@example.com",
"f_2_test_5@example.com"
};
public static readonly Liststring> File3 = new Liststring>
{
"f_3_test_1@example.com",
"f_3_test_2@example.com",
"f_3_test_3@example.com",
"f_3_test_4@example.com",
"f_3_test_5@example.com"
};
public static ListListstring>> GetMultiple
{
get
{
if (Contacts.Count = 0)
{
Contacts.Add(File1);
Contacts.Add(File2);
Contacts.Add(File3);
}
return Contacts;
}
}
}
}
6.到這里,我們的準備工作基本做得差不多了,最后我們只需要在DownloadController控制器中實現(xiàn)兩個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
{
}
}
}
}
}
到此,本示例的實現(xiàn)代碼部分就完成了,如果我們此時打開地址:http://localhost:63161/download/single,瀏覽器會彈出保存文件的提示窗口,如下:
![](/d/20211017/5e46e6e82b9f16dc9ffe59fde14bb01c.gif)
保存此文件后,打開它我們會看到我們的示例數(shù)據(jù)已被保存到本地了,如下:
![](/d/20211017/9228503881995a51143888a678e40c1e.gif)
同樣的,下載壓縮文件你只需要訪問地址:localhost:63161/download/zip 即可,筆者就不再演示了。
最后,附上本示例項目的完整源代碼,點擊這里下載。
以上就是本文的全部內容,希望能給大家一個參考,也希望大家多多支持腳本之家。
您可能感興趣的文章:- 創(chuàng)建一個完整的ASP.NET Web API項目
- ASP.NET中Web API的簡單實例
- ASP.NET MVC Web API HttpClient簡介
- 支持Ajax跨域訪問ASP.NET Web Api 2(Cors)的示例教程
- ASP.NET Web API教程 創(chuàng)建Admin視圖詳細介紹
- ASP.NET Web API如何將注釋自動生成幫助文檔
- ASP.NET Web API教程 創(chuàng)建Admin控制器實例分享
- ASP.NET Web API教程 創(chuàng)建域模型的方法詳細介紹
- .Net Web Api中利用FluentValidate進行參數(shù)驗證的方法