WebApi2 文件图片上传下载

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了WebApi2 文件图片上传下载相关的知识,希望对你有一定的参考价值。

Asp.Net Framework webapi2 文件上传与下载 前端界面采用Ajax的方式执行

一、项目结构

技术分享

1.App_Start配置了跨域访问,以免请求时候因跨域问题不能提交。具体的跨域配置方式如下,了解的朋友请自行略过。

跨域配置:NewGet安装dll Microsofg.AspNet.Cors

技术分享

然后在App_Start 文件夹下的WebApiConfig.cs中写入跨域配置代码。

 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     }

跨域就算完成了,请自行测试。

2.新建两个控制器,一个PicturesController.cs,一个FilesController.cs当然图片也是文件,这里图片和文件以不同的方式处理的,因为图片的方式文件上传没有成功,所以另寻他路,如果在座的有更好的方式,请不吝赐教!

二、项目代码

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帮助类里面写的,其实也仅仅是获取服务器根路径和如果判断文件夹不存在则创建目录,这两个代码的实现如下:

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                 //这种方式10kb内小文件没有问题,超出大小会失败
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的配置文件大小

<requestFiltering>
   <requestLimits maxAllowedContentLength="300000" />
</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="300000" />
11       </requestFiltering>
12     </security>
13   </system.webServer>

OK,共同学习~

以上是关于WebApi2 文件图片上传下载的主要内容,如果未能解决你的问题,请参考以下文章

java Ftp上传创建多层文件的代码片段

Android - 应用程序启动时片段 onCreate 崩溃

QT QHttpMultiPart上传图片

如何上传图片到七牛云

使用 AFNetworking、ios 上传图片

上传前调整图像大小 - 将画布转换为文件对象