這篇文章主要介紹了WebApi2 檔案圖片上傳與下載功能,需要的朋友可以參考下
Asp.Net Framework webapi2 檔案上傳與下載 前端介面採用Ajax的方式執行
一、項目結構
1.App_Start配置了跨域訪問,以免請求時候因跨域問題不能提交。具體的跨網域設定方式如下,瞭解的朋友請自行略過。
跨網域設定:NewGet安裝dll Microsofg.AspNet.Cors
然後在App_Start 檔案夾下的WebApiConfig.cs中寫入跨網域設定代碼。
public static class WebApiConfig { public static void Register(HttpConfiguration config) { // Web API configuration and services // Web API routes config.MapHttpAttributeRoutes(); // Web API configuration and services //跨網域設定 //need reference from nuget config.EnableCors(new EnableCorsAttribute("*", "*", "*")); config.Routes.MapHttpRoute( name: "DefaultApi", routeTemplate: "api/{controller}/{id}", defaults: new { id = RouteParameter.Optional } ); //if config the global filter input there need not write the attributes //config.Filters.Add(new App.WebApi.Filters.ExceptionAttribute_DG()); } }
跨域就算完成了,請自行測試。
2.建立兩個控制器,一個PicturesController.cs,一個FilesController.cs當然圖片也是檔案,這裡圖片和檔案以不同的方式處理的,因為圖片的方式檔案上傳沒有成功,所以另尋他路,如果在座的有更好的方式,請不吝賜教!
二、項目代碼
1.我們先說圖片上傳、下載控制器介面,這裡其實沒什麼好說的,就一個Get擷取檔案,參數是檔案全名;Post上傳檔案;直接上代碼。
using QX_Frame.App.WebApi;using QX_Frame.FilesCenter.Helper;using QX_Frame.Helper_DG;using QX_Frame.Helper_DG.Extends;using System;using System.Collections.Generic;using System.Diagnostics;using System.IO;using System.Linq;using System.Net;using System.Net.Http;using System.Net.Http.Headers;using System.Text;using System.Threading.Tasks;using System.Web.Http;/** * author:qixiao * create:2017-5-26 16:54:46 * */namespace QX_Frame.FilesCenter.Controllers{ public class PicturesController : WebApiControllerBase { //Get : api/Pictures public HttpResponseMessage Get(string fileName) { HttpResponseMessage result = null; DirectoryInfo directoryInfo = new DirectoryInfo(IO_Helper_DG.RootPath_MVC + @"Files/Pictures"); FileInfo foundFileInfo = directoryInfo.GetFiles().Where(x => x.Name == fileName).FirstOrDefault(); if (foundFileInfo != null) { FileStream fs = new FileStream(foundFileInfo.FullName, FileMode.Open); result = new HttpResponseMessage(HttpStatusCode.OK); result.Content = new StreamContent(fs); result.Content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/octet-stream"); result.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment"); result.Content.Headers.ContentDisposition.FileName = foundFileInfo.Name; } else { result = new HttpResponseMessage(HttpStatusCode.NotFound); } return result; } //POST : api/Pictures public async Task<IHttpActionResult> Post() { if (!Request.Content.IsMimeMultipartContent()) { throw new Exception_DG("unsupported media type", 2005); } string root = IO_Helper_DG.RootPath_MVC; IO_Helper_DG.CreateDirectoryIfNotExist(root + "/temp"); var provider = new MultipartFormDataStreamProvider(root + "/temp"); // Read the form data. await Request.Content.ReadAsMultipartAsync(provider); List<string> fileNameList = new List<string>(); StringBuilder sb = new StringBuilder(); long fileTotalSize = 0; int fileIndex = 1; // This illustrates how to get the file names. foreach (MultipartFileData file in provider.FileData) { //new folder string newRoot = root + @"Files/Pictures"; IO_Helper_DG.CreateDirectoryIfNotExist(newRoot); if (File.Exists(file.LocalFileName)) { //new fileName string fileName = file.Headers.ContentDisposition.FileName.Substring(1, file.Headers.ContentDisposition.FileName.Length - 2); string newFileName = Guid.NewGuid() + "." + fileName.Split('.')[1]; string newFullFileName = newRoot + "/" + newFileName; fileNameList.Add($"Files/Pictures/{newFileName}"); FileInfo fileInfo = new FileInfo(file.LocalFileName); fileTotalSize += fileInfo.Length; sb.Append($" #{fileIndex} Uploaded file: {newFileName} ({ fileInfo.Length} bytes)"); fileIndex++; File.Move(file.LocalFileName, newFullFileName); Trace.WriteLine("1 file copied , filePath=" + newFullFileName); } } return Json(Return_Helper.Success_Msg_Data_DCount_HttpCode($"{fileNameList.Count} file(s) /{fileTotalSize} bytes uploaded successfully! Details -> {sb.ToString()}", fileNameList, fileNameList.Count)); } }}
裡面可能有部分代碼在Helper協助類裡面寫的,其實也僅僅是擷取伺服器根路徑和如果判斷檔案夾不存在則建立目錄,這兩個代碼的實現如下:
public static string RootPath_MVC { get { return System.Web.HttpContext.Current.Server.MapPath("~"); } }//create Directory public static bool CreateDirectoryIfNotExist(string filePath) { if (!Directory.Exists(filePath)) { Directory.CreateDirectory(filePath); } return true; }
2.檔案上傳下載介面和圖片大同小異。
using QX_Frame.App.WebApi;using QX_Frame.FilesCenter.Helper;using QX_Frame.Helper_DG;using System.Collections.Generic;using System.Diagnostics;using System.IO;using System.Linq;using System.Net;using System.Net.Http;using System.Net.Http.Headers;using System.Text;using System.Threading.Tasks;using System.Web;using System.Web.Http;/** * author:qixiao * create:2017-5-26 16:54:46 * */namespace QX_Frame.FilesCenter.Controllers{ public class FilesController : WebApiControllerBase { //Get : api/Files public HttpResponseMessage Get(string fileName) { HttpResponseMessage result = null; DirectoryInfo directoryInfo = new DirectoryInfo(IO_Helper_DG.RootPath_MVC + @"Files/Files"); FileInfo foundFileInfo = directoryInfo.GetFiles().Where(x => x.Name == fileName).FirstOrDefault(); if (foundFileInfo != null) { FileStream fs = new FileStream(foundFileInfo.FullName, FileMode.Open); result = new HttpResponseMessage(HttpStatusCode.OK); result.Content = new StreamContent(fs); result.Content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/octet-stream"); result.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment"); result.Content.Headers.ContentDisposition.FileName = foundFileInfo.Name; } else { result = new HttpResponseMessage(HttpStatusCode.NotFound); } return result; } //POST : api/Files public async Task<IHttpActionResult> Post() { //get server root physical path string root = IO_Helper_DG.RootPath_MVC; //new folder string newRoot = root + @"Files/Files/"; //check path is exist if not create it IO_Helper_DG.CreateDirectoryIfNotExist(newRoot); List<string> fileNameList = new List<string>(); StringBuilder sb = new StringBuilder(); long fileTotalSize = 0; int fileIndex = 1; //get files from request HttpFileCollection files = HttpContext.Current.Request.Files; await Task.Run(() => { foreach (var f in files.AllKeys) { HttpPostedFile file = files[f]; if (!string.IsNullOrEmpty(file.FileName)) { string fileLocalFullName = newRoot + file.FileName; file.SaveAs(fileLocalFullName); fileNameList.Add($"Files/Files/{file.FileName}"); FileInfo fileInfo = new FileInfo(fileLocalFullName); fileTotalSize += fileInfo.Length; sb.Append($" #{fileIndex} Uploaded file: {file.FileName} ({ fileInfo.Length} bytes)"); fileIndex++; Trace.WriteLine("1 file copied , filePath=" + fileLocalFullName); } } }); return Json(Return_Helper.Success_Msg_Data_DCount_HttpCode($"{fileNameList.Count} file(s) /{fileTotalSize} bytes uploaded successfully! Details -> {sb.ToString()}", fileNameList, fileNameList.Count)); } }}
實現了上述兩個控制器代碼以後,我們需要前端代碼來調試對接,代碼如下所示。
<!doctype><head> <script src="jquery-3.2.0.min.js"></script> <!--<script src="jquery-1.11.1.js"></script>--> <!--<script src="ajaxfileupload.js"></script>--> <script> $(document).ready(function () { var appDomain = "http://localhost:3997/"; $("#btn_fileUpload").click(function () { /** * 用ajax方式上傳檔案 ----------- * */ //-------asp.net webapi fileUpload // var formData = new FormData($("#uploadForm")[0]); $.ajax({ url: appDomain + 'api/Files', type: 'POST', data: formData, async: false, cache: false, contentType: false, processData: false, success: function (data) { console.log(JSON.stringify(data)); }, error: function (data) { console.log(JSON.stringify(data)); } }); //----end asp.net webapi fileUpload //----.net core webapi fileUpload // var fileUpload = $("#files").get(0); // var files = fileUpload.files; // var data = new FormData(); // for (var i = 0; i < files.length; i++) { // data.append(files[i].name, files[i]); // } // $.ajax({ // type: "POST", // url: appDomain+'api/Files', // contentType: false, // processData: false, // data: data, // success: function (data) { // console.log(JSON.stringify(data)); // }, // error: function () { // console.log(JSON.stringify(data)); // } // }); //--------end net core webapi fileUpload /** * ajaxfileupload.js 方式上傳檔案 * */ // $.ajaxFileUpload({ // type: 'post', // url: appDomain + 'api/Files', // secureuri: false, // fileElementId: 'files', // success: function (data) { // console.log(JSON.stringify(data)); // }, // error: function () { // console.log(JSON.stringify(data)); // } // }); }); //end click }) </script></head><title></title><body> <article> <header> <h2>article-form</h2> </header> <p> <form action="/" method="post" id="uploadForm" enctype="multipart/form-data"> <input type="file" id="files" name="files" placeholder="file" multiple>file-multiple屬性可以選擇多項<br><br> <input type="button" id="btn_fileUpload" value="fileUpload"> </form> </p> </article></body>
至此,我們的功能已全部實現,下面我們來測試一下:
可見,檔案上傳成功,按預期格式返回!
下面我們測試單圖片上傳->
然後我們按返回的地址進行訪問圖片地址。
發現並無任何壓力!
下面測試多圖片上傳->
完美~
至此,我們已經實現了WebApi2檔案和圖片上傳,下載的全部功能。
這裡需要注意一下Web.config的配置上傳檔案支援的總大小,我這裡配置的是最大支援的檔案大小為1MB
<requestFiltering> <requestLimits maxAllowedContentLength="1048576" /></requestFiltering> <system.webServer> <handlers> <remove name="ExtensionlessUrlHandler-Integrated-4.0" /> <remove name="OPTIONSVerbHandler" /> <remove name="TRACEVerbHandler" /> <add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" /> </handlers> <security> <requestFiltering> <requestLimits maxAllowedContentLength="1048576" /><!--1MB--> </requestFiltering> </security> </system.webServer>
【相關推薦】
1. ASP.NET免費視頻教程
2. 詳細介紹ASP.NET MVC--路由
3. 詳細介紹ASP.NET MVC--控制器(controller)
4. 詳細介紹ASP.NET MVC--視圖