ASP.NET MVC 檔案上傳和檔案下載 以及 檔案下載的幾種方法
1、序言
最近專案中需要用到這個功能點,但是網上下載的時候總是出現亂碼。所以趁著這個時間自己整理出了一份,以後需要的時候就直接看自己的部落格就行了。已經測試過:在谷歌、火狐、IE等瀏覽器上都不會出現亂碼問題。
2、結果展示
2.1、上傳檔案成功介面
2.2、下載檔案成功介面
3、上傳檔案程式碼
3.1、View程式碼
@model System.Web.HttpContextBase @{ ViewBag.Title = "上傳檔案"; } <h2>上傳檔案</h2> <br /> <br /> @*new { enctype = "multipart/form-data" }比不可少,否則上傳檔案不會成功 *@ @using (Html.BeginForm("Upload", "UploadFile", FormMethod.Post, new { enctype = "multipart/form-data" })) { <text>選擇上傳檔案:</text><input name="file" type="file" id="file" /> <br /> <br /> <input type="submit" name="Upload" value="Upload" /> }
3.2、Controller程式碼
[HttpPost] public ActionResult Upload(FormCollection form) { if (Request.Files.Count == 0){ //Request.Files.Count 檔案數為0上傳不成功 return View(); } var file = Request.Files[0]; if (file.ContentLength == 0){ //檔案大小大(以位元組為單位)為0時,做一些操作 return View(); } else{ //檔案大小不為0 file = Request.Files[0]; //儲存成自己的檔案全路徑,newfile就是你上傳後儲存的檔案, //伺服器上的UpLoadFile資料夾必須有讀寫許可權 string target = Server.MapPath("/")+("/Mock/Learning/");//取得目標資料夾的路徑 string filename = file.FileName;//取得檔名字 string path = target + filename;//獲取儲存的目標地址 file.SaveAs(path);} return View(); }
4、下載檔案程式碼
4.1、View程式碼
<a href="/DownloadFile/[email protected]&fileName='小王子.pdf'">下載</a>
4.2、Controller程式碼
public ActionResult Download(string filePath, string fileName) { Encoding encoding; string outputFileName = null; fileName = fileName.Replace("'", ""); string browser =Request.UserAgent.ToUpper(); if (browser.Contains("MS") == true && browser.Contains("IE") == true) { outputFileName = HttpUtility.UrlEncode(fileName); encoding =Encoding.Default; } else if (browser.Contains("FIREFOX") == true) { outputFileName = fileName; encoding =Encoding.GetEncoding("GB2312"); } else { outputFileName = HttpUtility.UrlEncode(fileName); encoding = Encoding.Default; } FileStream fs = new FileStream(filePath, FileMode.Open); byte[] bytes = new byte[(int)fs.Length]; fs.Read(bytes, 0, bytes.Length); fs.Close(); Response.Charset = "UTF-8"; Response.ContentType = "application/octet-stream"; Response.ContentEncoding = encoding; Response.AddHeader("Content-Disposition", "attachment; filename=" + outputFileName); Response.BinaryWrite(bytes); Response.Flush(); Response.End(); return new EmptyResult(); }
在ASP.net MVC 中有幾種下載檔案的方法
前提:要下載的檔案必須是在伺服器目錄中的,至於不在web專案server目錄中的檔案下載我不知道,但是還挺想了解的。
第一種:最簡單的超連結方法,<a>標籤的href直接指向目標檔案地址,這樣容易暴露地址造成盜鏈,這裡就不說了
第二種:後臺下載
在後臺下載中又可以細分為幾種下載方式
首先,在前臺,我們需要一個<a>標籤
<a href="~/Home/download">Click to get file</a>
Home為controller,download為action。
如果需要傳一些引數,可以:
<a href="~/Home/download?id=1">Click to get file</a>
在後臺:
(1)返回filestream
public FileStreamResult download() { string fileName = "aaa.txt";//客戶端儲存的檔名 string filePath = Server.MapPath("~/Document/123.txt");//路徑 return File(new FileStream(filePath, FileMode.Open), "text/plain", fileName); }
其中:“text/plain”是檔案MIME型別
(2)返回file
public FileResult download() { string filePath = Server.MapPath("~/Document/123.txt");//路徑 return File(filePath, "text/plain", "welcome.txt"); //welcome.txt是客戶端儲存的名字 }
(3)TransmitFile方法
1 public void download() 2 { 3 string fileName = "aaa.txt";//客戶端儲存的檔名 4 string filePath = Server.MapPath("~/Document/123.txt");//路徑 5 FileInfo fileinfo = new FileInfo(filePath); 6 Response.Clear(); //清除緩衝區流中的所有內容輸出 7 Response.ClearContent(); //清除緩衝區流中的所有內容輸出 8 Response.ClearHeaders(); //清除緩衝區流中的所有頭 9 Response.Buffer = true; //該值指示是否緩衝輸出,並在完成處理整個響應之後將其傳送 10 Response.AddHeader("Content-Disposition", "attachment;filename=" + fileName); 11 Response.AddHeader("Content-Length",fileinfo.Length.ToString()); 12 Response.AddHeader("Content-Transfer-Encoding", "binary"); 13 Response.ContentType = "application/unknow"; //獲取或設定輸出流的 HTTP MIME 型別 14 Response.ContentEncoding = System.Text.Encoding.GetEncoding("gb2312"); //獲取或設定輸出流的 HTTP 字符集 15 Response.TransmitFile(filePath); 16 Response.End(); 17 }
(4)Response分塊下載
1 public void download() 2 { 3 string fileName = "aaa.txt";//客戶端儲存的檔名 4 string filePath = Server.MapPath("~/Document/123.txt");//路徑 5 6 System.IO.FileInfo fileInfo = new System.IO.FileInfo(filePath); 7 if (fileInfo.Exists == true) 8 { 9 const long ChunkSize = 102400;//100K 每次讀取檔案,只讀取100K,這樣可以緩解伺服器的壓力 10 byte[] buffer = new byte[ChunkSize]; 11 12 Response.Clear(); 13 System.IO.FileStream iStream = System.IO.File.OpenRead(filePath); 14 long dataLengthToRead = iStream.Length;//獲取下載的檔案總大小 15 Response.ContentType = "application/octet-stream"; 16 Response.AddHeader("Content-Disposition", "attachment; filename=" + HttpUtility.UrlEncode(fileName)); 17 while (dataLengthToRead > 0 && Response.IsClientConnected) 18 { 19 int lengthRead = iStream.Read(buffer, 0, Convert.ToInt32(ChunkSize));//讀取的大小 20 Response.OutputStream.Write(buffer, 0, lengthRead); 21 Response.Flush(); 22 dataLengthToRead = dataLengthToRead - lengthRead; 23 } 24 Response.Close(); 25 } 26 }
<input>+ajax方法
要重點說說這個方法,ajax返回不了檔案流,所以說用ajax呼叫上面任意一種後臺方法都要出問題,下載不了檔案。
所以,只能讓後臺返回所需下載檔案的url地址,然後呼叫windows.location.href。
優點:ajax可以傳好幾個引數(當然以json形式),傳100個都無所謂。你要是用<a href="網址?引數=值"></a>的方法傳100得寫死。。。(公司需求,至少要傳100多個引數)
缺點:支援下載exe,rar,msi等型別檔案。對於txt則會直接開啟,慎用!對於其他不常用的型別檔案則直接報錯。
所以我的建議是得到多個引數,通過資料庫找到所有需要下載的檔案然後壓縮打包,然後返回url下載。(你要是一個一個給使用者下,使用者都瘋了)
!那麼問題又來了,C#怎麼用程式碼實現將本地的一些檔案打包壓縮到伺服器目錄下呢?這我不知道。
因為你只是單純的放在目錄資料夾下沒有用的,我們平時在伺服器某目錄下新增某一個檔案都是右鍵,新增XXX項這樣,這樣才能真正的將檔案放在伺服器中。
可是純程式碼該怎麼實現呢??
*可能的解決方法:先在專案目錄下放一個空的rar檔案或者沒什麼功能的exe,msi檔案,然後在後臺打包完一些檔案後去替換它,不知道可行不。
(1)首先清空原壓縮包中的內容
(2)將檔案壓縮到壓縮包中
(3)返回 XXX.rar
前端:
<input type="button" id="downloadbutton"/>
ajax:
$("#downloadbutton").click(function () { $.ajax({ type: "GET", url: "/Home/download", data: { id: "1" }, dataType:"json", success: function (result) { window.location.target = "_blank"; window.location.href = result; } }) })
後臺:
public string download(int id) { string filePath = "Document/123.msi";//路徑 return filePath; }
這裡,id是沒有什麼作用的,後臺就別用什麼server.Mappath了,肯定錯。直接寫伺服器專案資料夾/檔名 即可。
前言
這一節我們來講講在MVC中如何進行檔案的上傳,我們逐步深入,一起來看看。
Upload File(一)
我們在預設建立的專案中的Home控制器下新增如下:
public ActionResult UploadFile() { return View(); } [HttpPost] public ActionResult UploadFile(HttpPostedFileBase file) { var fileName = file.FileName; var filePath = Server.MapPath(string.Format("~/{0}", "File")); file.SaveAs(Path.Combine(filePath, fileName)); return View(); }
在 UploadFile 檢視中新增上如下:
<form action="/Home/UploadFile" method="post" enctype="multipart/form-data"> <input type="file" name="file" /><br /> <input type="submit" value="提交" /> </form>
有關檢視中我們就不必多說,只需明白如下兩點:
(1)在後臺利用HttpPostedFileBase來接收上傳檔案,該類為一個抽象類,但在ASP.NET Web Form卻沒有此類,此類的出現是為了更好的進行單元測試。
(2)在檢視中檔案型別的name要和後臺接收檔案的引數一致。
接下來我們進行演示看看結果:
上述我們簡單的上傳了一個Excel檔案,下面我們通過強型別檢視以及模型驗證來強化上傳。
Upload File(二)
我們建立如下BlogModel類:
public class BlogModel { [Display(Name = "部落格名稱")] [Required(ErrorMessage = "請輸入你的部落格名稱!")] public string BlogName { get; set; } [Display(Name = "部落格地址")] [Required(ErrorMessage = "請輸入你的部落格地址!")] public string BlogAddress { get; set; } [Display(Name = "部落格圖片")] [Required(ErrorMessage = "請上傳你的部落格圖片!")] [ValidateFile] public HttpPostedFileBase BlogPhoto { get; set; } }