Asp.Net Framework webapi2 文件上傳與下載 前端界面採用Ajax的方式執行前端
1、項目結構jquery
1.App_Start配置了跨域訪問,以避免請求時候因跨域問題不能提交。具體的跨域配置方式以下,瞭解的朋友請自行略過。git
跨域配置:NewGet安裝dll Microsofg.AspNet.Corsgithub
而後在App_Start 文件夾下的WebApiConfig.cs中寫入跨域配置代碼。web
1 public static class WebApiConfig 2 { 3 public static void Register(HttpConfiguration config) 4 { 5 // Web API configuration and services 6 7 // Web API routes 8 config.MapHttpAttributeRoutes(); 9 10 // Web API configuration and services 11 //跨域配置 //need reference from nuget 12 config.EnableCors(new EnableCorsAttribute("*", "*", "*")); 13 14 config.Routes.MapHttpRoute( 15 name: "DefaultApi", 16 routeTemplate: "api/{controller}/{id}", 17 defaults: new { id = RouteParameter.Optional } 18 ); 19 20 //if config the global filter input there need not write the attributes 21 //config.Filters.Add(new App.WebApi.Filters.ExceptionAttribute_DG()); 22 } 23 }
跨域就算完成了,請自行測試。ajax
2.新建兩個控制器,一個PicturesController.cs,一個FilesController.cs固然圖片也是文件,這裏圖片和文件以不一樣的方式處理的,由於圖片的方式文件上傳沒有成功,因此另尋他路,若是在座的有更好的方式,請不吝賜教!api
2、項目代碼跨域
1.咱們先說圖片上傳、下載控制器接口,這裏其實沒什麼好說的,就一個Get獲取文件,參數是文件全名;Post上傳文件;直接上代碼。服務器
1 using QX_Frame.App.WebApi; 2 using QX_Frame.FilesCenter.Helper; 3 using QX_Frame.Helper_DG; 4 using QX_Frame.Helper_DG.Extends; 5 using System; 6 using System.Collections.Generic; 7 using System.Diagnostics; 8 using System.IO; 9 using System.Linq; 10 using System.Net; 11 using System.Net.Http; 12 using System.Net.Http.Headers; 13 using System.Text; 14 using System.Threading.Tasks; 15 using System.Web.Http; 16 17 /** 18 * author:qixiao 19 * create:2017-5-26 16:54:46 20 * */ 21 namespace QX_Frame.FilesCenter.Controllers 22 { 23 public class PicturesController : WebApiControllerBase 24 { 25 //Get : api/Pictures 26 public HttpResponseMessage Get(string fileName) 27 { 28 HttpResponseMessage result = null; 29 30 DirectoryInfo directoryInfo = new DirectoryInfo(IO_Helper_DG.RootPath_MVC + @"Files/Pictures"); 31 FileInfo foundFileInfo = directoryInfo.GetFiles().Where(x => x.Name == fileName).FirstOrDefault(); 32 if (foundFileInfo != null) 33 { 34 FileStream fs = new FileStream(foundFileInfo.FullName, FileMode.Open); 35 36 result = new HttpResponseMessage(HttpStatusCode.OK); 37 result.Content = new StreamContent(fs); 38 result.Content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/octet-stream"); 39 result.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment"); 40 result.Content.Headers.ContentDisposition.FileName = foundFileInfo.Name; 41 } 42 else 43 { 44 result = new HttpResponseMessage(HttpStatusCode.NotFound); 45 } 46 47 return result; 48 } 49 50 51 //POST : api/Pictures 52 public async Task<IHttpActionResult> Post() 53 { 54 if (!Request.Content.IsMimeMultipartContent()) 55 { 56 throw new Exception_DG("unsupported media type", 2005); 57 } 58 string root = IO_Helper_DG.RootPath_MVC; 59 60 IO_Helper_DG.CreateDirectoryIfNotExist(root + "/temp"); 61 62 var provider = new MultipartFormDataStreamProvider(root + "/temp"); 63 64 // Read the form data. 65 await Request.Content.ReadAsMultipartAsync(provider); 66 67 List<string> fileNameList = new List<string>(); 68 69 StringBuilder sb = new StringBuilder(); 70 71 long fileTotalSize = 0; 72 73 int fileIndex = 1; 74 75 // This illustrates how to get the file names. 76 foreach (MultipartFileData file in provider.FileData) 77 { 78 //new folder 79 string newRoot = root + @"Files/Pictures"; 80 81 IO_Helper_DG.CreateDirectoryIfNotExist(newRoot); 82 83 if (File.Exists(file.LocalFileName)) 84 { 85 //new fileName 86 string fileName = file.Headers.ContentDisposition.FileName.Substring(1, file.Headers.ContentDisposition.FileName.Length - 2); 87 88 string newFileName = Guid.NewGuid() + "." + fileName.Split('.')[1]; 89 90 string newFullFileName = newRoot + "/" + newFileName; 91 92 fileNameList.Add($"Files/Pictures/{newFileName}"); 93 94 FileInfo fileInfo = new FileInfo(file.LocalFileName); 95 96 fileTotalSize += fileInfo.Length; 97 98 sb.Append($" #{fileIndex} Uploaded file: {newFileName} ({ fileInfo.Length} bytes)"); 99 100 fileIndex++; 101 102 File.Move(file.LocalFileName, newFullFileName); 103 104 Trace.WriteLine("1 file copied , filePath=" + newFullFileName); 105 } 106 } 107 108 return Json(Return_Helper.Success_Msg_Data_DCount_HttpCode($"{fileNameList.Count} file(s) /{fileTotalSize} bytes uploaded successfully! Details -> {sb.ToString()}", fileNameList, fileNameList.Count)); 109 } 110 } 111 }
裏面可能有部分代碼在Helper幫助類裏面寫的,其實也僅僅是獲取服務器根路徑和若是判斷文件夾不存在則建立目錄,這兩個代碼的實現以下:app
1 public static string RootPath_MVC 2 { 3 get { return System.Web.HttpContext.Current.Server.MapPath("~"); } 4 }
1 //create Directory 2 public static bool CreateDirectoryIfNotExist(string filePath) 3 { 4 if (!Directory.Exists(filePath)) 5 { 6 Directory.CreateDirectory(filePath); 7 } 8 return true; 9 }
2.文件上傳下載接口和圖片大同小異。
1 using QX_Frame.App.WebApi; 2 using QX_Frame.FilesCenter.Helper; 3 using QX_Frame.Helper_DG; 4 using System.Collections.Generic; 5 using System.Diagnostics; 6 using System.IO; 7 using System.Linq; 8 using System.Net; 9 using System.Net.Http; 10 using System.Net.Http.Headers; 11 using System.Text; 12 using System.Threading.Tasks; 13 using System.Web; 14 using System.Web.Http; 15 16 /** 17 * author:qixiao 18 * create:2017-5-26 16:54:46 19 * */ 20 namespace QX_Frame.FilesCenter.Controllers 21 { 22 public class FilesController : WebApiControllerBase 23 { 24 //Get : api/Files 25 public HttpResponseMessage Get(string fileName) 26 { 27 HttpResponseMessage result = null; 28 29 DirectoryInfo directoryInfo = new DirectoryInfo(IO_Helper_DG.RootPath_MVC + @"Files/Files"); 30 FileInfo foundFileInfo = directoryInfo.GetFiles().Where(x => x.Name == fileName).FirstOrDefault(); 31 if (foundFileInfo != null) 32 { 33 FileStream fs = new FileStream(foundFileInfo.FullName, FileMode.Open); 34 35 result = new HttpResponseMessage(HttpStatusCode.OK); 36 result.Content = new StreamContent(fs); 37 result.Content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/octet-stream"); 38 result.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment"); 39 result.Content.Headers.ContentDisposition.FileName = foundFileInfo.Name; 40 } 41 else 42 { 43 result = new HttpResponseMessage(HttpStatusCode.NotFound); 44 } 45 46 return result; 47 } 48 49 //POST : api/Files 50 public async Task<IHttpActionResult> Post() 51 { 52 //get server root physical path 53 string root = IO_Helper_DG.RootPath_MVC; 54 55 //new folder 56 string newRoot = root + @"Files/Files/"; 57 //check path is exist if not create it 58 IO_Helper_DG.CreateDirectoryIfNotExist(newRoot); 59 60 List<string> fileNameList = new List<string>(); 61 62 StringBuilder sb = new StringBuilder(); 63 64 long fileTotalSize = 0; 65 66 int fileIndex = 1; 67 68 //get files from request 69 HttpFileCollection files = HttpContext.Current.Request.Files; 70 71 await Task.Run(() => 72 { 73 foreach (var f in files.AllKeys) 74 { 75 HttpPostedFile file = files[f]; 76 if (!string.IsNullOrEmpty(file.FileName)) 77 { 78 79 string fileLocalFullName = newRoot + file.FileName; 80 81 file.SaveAs(fileLocalFullName); 82 83 fileNameList.Add($"Files/Files/{file.FileName}"); 84 85 FileInfo fileInfo = new FileInfo(fileLocalFullName); 86 87 fileTotalSize += fileInfo.Length; 88 89 sb.Append($" #{fileIndex} Uploaded file: {file.FileName} ({ fileInfo.Length} bytes)"); 90 91 fileIndex++; 92 93 Trace.WriteLine("1 file copied , filePath=" + fileLocalFullName); 94 } 95 } 96 }); 97 98 99 return Json(Return_Helper.Success_Msg_Data_DCount_HttpCode($"{fileNameList.Count} file(s) /{fileTotalSize} bytes uploaded successfully! Details -> {sb.ToString()}", fileNameList, fileNameList.Count)); 100 } 101 } 102 }
實現了上述兩個控制器代碼之後,咱們須要前端代碼來調試對接,代碼以下所示。
1 <!doctype> 2 3 <head> 4 <script src="jquery-3.2.0.min.js"></script> 5 <!--<script src="jquery-1.11.1.js"></script>--> 6 <!--<script src="ajaxfileupload.js"></script>--> 7 <script> 8 $(document).ready(function () { 9 var appDomain = "http://localhost:3997/"; 10 11 12 $("#btn_fileUpload").click(function () { 13 14 /** 15 * 用ajax方式上傳文件 ----------- 16 * */ 17 //-------asp.net webapi fileUpload 18 // 19 var formData = new FormData($("#uploadForm")[0]); 20 $.ajax({ 21 url: appDomain + 'api/Files', 22 type: 'POST', 23 data: formData, 24 async: false, 25 cache: false, 26 contentType: false, 27 processData: false, 28 success: function (data) { 29 console.log(JSON.stringify(data)); 30 }, 31 error: function (data) { 32 console.log(JSON.stringify(data)); 33 } 34 }); 35 //----end asp.net webapi fileUpload 36 37 //----.net core webapi fileUpload 38 // var fileUpload = $("#files").get(0); 39 // var files = fileUpload.files; 40 // var data = new FormData(); 41 // for (var i = 0; i < files.length; i++) { 42 // data.append(files[i].name, files[i]); 43 // } 44 // $.ajax({ 45 // type: "POST", 46 // url: appDomain+'api/Files', 47 // contentType: false, 48 // processData: false, 49 // data: data, 50 // success: function (data) { 51 // console.log(JSON.stringify(data)); 52 // }, 53 // error: function () { 54 // console.log(JSON.stringify(data)); 55 // } 56 // }); 57 //--------end net core webapi fileUpload 58 59 /** 60 * ajaxfileupload.js 方式上傳文件 61 * */ 62 // $.ajaxFileUpload({ 63 // type: 'post', 64 // url: appDomain + 'api/Files', 65 // secureuri: false, 66 // fileElementId: 'files', 67 // success: function (data) { 68 // console.log(JSON.stringify(data)); 69 // }, 70 // error: function () { 71 // console.log(JSON.stringify(data)); 72 // } 73 // }); 74 75 }); 76 //end click 77 78 79 }) 80 </script> 81 </head> 82 <title></title> 83 84 <body> 85 <article> 86 <header> 87 <h2>article-form</h2> 88 </header> 89 <p> 90 <form action="/" method="post" id="uploadForm" enctype="multipart/form-data"> 91 <input type="file" id="files" name="files" placeholder="file" multiple>file-multiple屬性能夠選擇多項<br><br> 92 <input type="button" id="btn_fileUpload" value="fileUpload"> 93 </form> 94 </p> 95 </article> 96 </body>
至此,咱們的功能已所有實現,下面咱們來測試一下:
可見,文件上傳成功,按預期格式返回!
下面咱們測試單圖片上傳->
而後咱們按返回的地址進行訪問圖片地址。
發現並沒有任何壓力!
下面測試多圖片上傳->
完美~
至此,咱們已經實現了WebApi2文件和圖片上傳,下載的所有功能。
這裏須要注意一下Web.config的配置上傳文件支持的總大小,我這裏配置的是最大支持的文件大小爲1MB
<requestFiltering> <requestLimits maxAllowedContentLength="1048576" /> </requestFiltering>
1 <system.webServer> 2 <handlers> 3 <remove name="ExtensionlessUrlHandler-Integrated-4.0" /> 4 <remove name="OPTIONSVerbHandler" /> 5 <remove name="TRACEVerbHandler" /> 6 <add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" /> 7 </handlers> 8 <security> 9 <requestFiltering> 10 <requestLimits maxAllowedContentLength="1048576" /><!--1MB--> 11 </requestFiltering> 12 </security> 13 </system.webServer>
OK,共同窗習~
該項目已遷移成文件中心(專用來處理文件上傳下載的接口),GitHub地址:https://github.com/dong666/QX_Frame.FilesCenter