本地服务的文件上传与远程服务的文件上传(图片上传)

  • A+
所属分类:.NET技术
摘要

文件上传属于常见业务,很多地方都用的到(比如图片上传);确切的说,这里的“本地”是指的项目所在的服务端,只是在项目服务端再次请求另外一个服务端进行文件二次上传。

文件上传属于常见业务,很多地方都用的到(比如图片上传);

确切的说,这里的“本地”是指的项目所在的服务端,只是在项目服务端再次请求另外一个服务端进行文件二次上传。

比如:我们上传图片的时候,请求项目的服务器需要上传一份,同时还要上传一份到cdn服务器。

示例使用控件: el-upload 作为演示

本地服务的文件上传与远程服务的文件上传(图片上传)

本地服务的文件上传与远程服务的文件上传(图片上传)本地服务的文件上传与远程服务的文件上传(图片上传)

 1 <style>  2         .uploader {  3             border: 1px dashed #d9d9d9;  4             border-radius: 6px;  5             cursor: pointer;  6             position: relative;  7             overflow: hidden;  8         }  9  10             .uploader:hover { 11                 border-color: #409EFF; 12             } 13  14         .avatar-uploader-icon { 15             font-size: 28px; 16             color: #8c939d; 17             text-align: center; 18         } 19  20         .banners-size { 21             width: 280px; 22             height: 120px; 23             line-height: 120px; 24         } 25  26         .avatar-banners { 27             width: 280px; 28             height: 120px; 29             background-size: cover; 30         } 31  32         .el-upload__tip { 33             color: red; 34         } 35     </style>

View Code

 1 <el-upload class="upload-demo"  2            ref="banners"  3            :limit="1"  4            action="https://jsonplaceholder.typicode.com/posts/"  5            accept="image/jpeg,image/png"  6            name="bannersImg"  7            :http-request="uploadFile"  8            :auto-upload="false">  9     <el-button slot="trigger" size="small" type="primary" v-on:click="selectUpload('bannersImg')">选取文件</el-button> 10     <el-button style="margin-left: 10px;" size="small" type="success" v-on:click="submitUpload('bannersImg')">确定上传</el-button> 11     <div slot="tip" class="el-upload__tip">只能上传jpg文件,且不超过200kb,尺寸:440x240</div> 12 </el-upload> 13 <div class="uploader banners-size"> 14     <img v-if="banners_imageUrl" :src="banners_imageUrl" class="avatar-banners"> 15 </div>

前端核心代码:

本地服务的文件上传与远程服务的文件上传(图片上传)本地服务的文件上传与远程服务的文件上传(图片上传)

 1                //选取文件  2                 selectUpload: function (obj) {  3                     this.clearFiles(obj);  4                 },  5                 //确定上传  6                 submitUpload: function (obj) {  7                      this.$refs.banners.submit();  8                 },  9                 //清除文件状态 10                 clearFiles: function (filename) { 11                       this.$refs.banners.clearFiles(); 12                 }, 13  14                 //文件上传 15                 uploadFile: function (params) { 16                     //console.log(params); 17                     var _filename = params.filename; 18  19                     //判断图片格式 20                     const isJPG = params.file.type === 'image/jpeg'; 21                     if (!isJPG) { 22                         this.$message.error('上传图片只能是 JPG 格式!'); 23                         this.clearFiles(_filename); 24                         return isJPG; 25                     } 26                      this.BannersUpload(params.file); 27                 }, 28                 //图片上传 29                 BannersUpload: function (file) { 30                     const isLtSize = file.size / 1024 / 1024 / 1024 < 20;  //不能超过xx kb 31                     if (!isLtSize) { 32                         this.$message.error('上传图片大小不能超过 20kb!'); 33                         this.clearFiles(file.filename); 34                         return isLtSize; 35                     } 36  37                     //执行上传操作 38                     this.FileUpload(file) 39                         .then(res => {   //返回结果 40                             var getResult = JSON.parse(res.data); 41                             //成功 42                             if (getResult.Code == 0) { 43                                 this.$message.success('上传成功'); 44                                 this.banners_imageUrl = getResult.Data; 45                                 this.addForm.BannersImg = getResult.Data; 46                             } 47                             //错误 48                             if (getResult.Code == 1) { 49                                 if (getResult.Message) { 50                                     this.$message.error(getResult.Message); 51                                 } 52                             } 53                         }).catch(function (res) { 54                             this.$message.success('请求异常'); 55                         }); 56                 }, 57                 //文件上传 58                 FileUpload: function (file) { 59                     var fd = new FormData(); 60                     fd.append("filedata", file); 61                     //异步获取 62                     return axios.request({ 63                         method: 'post', 64                         baseURL: this.apiUrl, 65                         url: '/WxLive/UploadImg', 66                         params: { "filename": "filedata" },   //是即将与请求一起发送的 URL 参数 67                         data: fd,     //浏览器专属:FormData, File, Blob  必须是以下类型之一:string, plain object, ArrayBuffer, ArrayBufferView, URLSearchParams 68                         headers: { "Content-Type": "multipart/form-data;charset=UTF-8" }, 69                     }); 70                 }

View Code

本地服务器上传接口:

本地服务的文件上传与远程服务的文件上传(图片上传)本地服务的文件上传与远程服务的文件上传(图片上传)

 1         /// <summary>  2         /// 本地上传图片  3         /// </summary>  4         /// <returns></returns>  5         [HttpPost]  6         public JsonResult UploadImg(string filename)  7         {  8             var result = new Common.CommonResult(1, "网络请求错误");  9             try 10             { 11                 string basePath = ConfigurationManager.AppSettings["basePath"] ?? "\Images";    //服务器上传文件夹 12                 string imgpath = string.Empty; 13  14                 HttpPostedFileBase file = Request.Files.Get(filename);  //从browser传过来的的文件 15                 //HttpPostedFile file = System.Web.HttpContext.Current.Request.Files.Get(filename);  //从browser传过来的的文件 16  17                 if (file != null && file.ContentLength > 0) 18                 { 19                     //文件后缀名 20                     string fileExtension = Path.GetExtension(file.FileName).ToLower(); 21  22                     //获取文件名 23                     string fileName = DateTime.Now.ToString("yyyy_MM_dd_HH_mm_ss_ffff"); 24                     fileName += fileExtension; 25  26                     Stream postStream = file.InputStream; 27                     byte[] bytes = new byte[postStream.Length]; 28                     postStream.Read(bytes, 0, file.ContentLength); 29                     postStream.Seek(0, SeekOrigin.Begin);    //设置当前流的位置为流的开始  30                     postStream.Close(); 31  32                     //写入本地 33                     var repath = UploadHelper.UploadFile(bytes, basePath, fileName); 34  35                     result.Code = 0; 36                     result.Message = "OK"; 37                     result.Data = repath; 38                 } 39                 return Json(JsonConvert.SerializeObject(result)); 40             } 41             catch (Exception) 42             { 43                 return Json(JsonConvert.SerializeObject(result)); 44             } 45         }

View Code

上传本地文件处理方法:UploadHelper.UploadFile()

 1         /// <summary>  2         /// 上传文件到本地  3         /// </summary>  4         /// <param name="filename"></param>  5         /// <param name="basePath"></param>  6         /// <param name="bytes"></param>  7         /// <returns></returns>  8         public static string UploadFile(byte[] bytes,string basePath, string filename)  9         { 10             string result = ""; 11             try 12             { 13                 if (bytes != null) 14                 { 15                     //保存文件路径,比如:\Images\2020-01-01\,这里的basePath相当于\Images 16                     string upfilePath = basePath + "\" + DateTime.Now.ToString("yyyy-MM-dd") + "\";  //根路径 17                     //上传到本地  ~/表示上级目录,如果不加则表示同级目录 18                     string filePath = System.Web.HttpContext.Current.Server.MapPath("~/" + upfilePath); 19                     if (!Directory.Exists(filePath)) 20                     { 21                         Directory.CreateDirectory(filePath); 22                     } 23                     //完整路径:项目目录\Images\2020-01-01\abc.jpg 24                     string fileSavePath = Path.Combine(filePath, filename);  //合并成完整的文件路径 25  26                     //写入本地 27                     using (FileStream fs = new FileStream(fileSavePath, FileMode.Create)) 28                     { 29                         fs.Write(bytes, 0, bytes.Length); 30                         fs.Close(); 31                         fs.Dispose(); 32                     } 33                     //返回路径:/Images/2020-01-01/abc.jpg 34                     result = (upfilePath + filename).Replace("\", "/"); 35                 } 36                 else 37                 { 38                     result = "上传的文件信息不存在!"; 39                 } 40             } 41             catch (Exception ex) 42             { 43                 return ""; 44             } 45             return result; 46         }

一般向本地服务器上传的同时,还要向cdn服务器上传一份,请求cdn服务器接口代码如下:

 1         /// <summary>  2         /// 上传文件到远程服务器  3         /// </summary>  4         /// <param name="bytes"></param>  5         /// <param name="basepath"></param>  6         /// <param name="filename"></param>  7         /// <returns></returns>  8         public static string PostUploadFile(byte[] bytes, string basepath, string filename)  9         { 10             string repath = ""; 11             string hosturl = ConfigurationManager.AppSettings["apihost"] ?? "https://cache.xxxxxx.com:8080/";    //远程服务器路径 12             try 13             { 14                 var apiurl = hosturl + "api/UpLoad/ReceiveFile";  //远程请求接口 相当于:https://cache.xxxxxx.com:8080/api/UpLoad/ReceiveFile 15                 HttpClient httpClient = HttpClientFactory.GetHttpClient(); 16                 string upfilePath = basepath + "\" + DateTime.Now.ToString("yyyy-MM-dd") + "\";  //保存路径,比如:\Images\2020-01-01\,basepath相当于\Images 17                 using (var multipartFormDataContent = new MultipartFormDataContent())  //MultipartFormDataContent相当于 "Content-Type": "multipart/form-data" 18                 { 19                     //二进制流传输,远程服务器可以使用: Request.Files.Get("filedata")接收 20                     multipartFormDataContent.Add(new ByteArrayContent(bytes, 0, bytes.Length), "filedata", filename); 21                     //远程服务器可以使用: Request["filePath"]接收 22                     multipartFormDataContent.Add(new StringContent(upfilePath, Encoding.UTF8, "application/x-www-form-urlencoded"), "filePath"); 23  24                     //post请求 25                     var response = httpClient.PostAsync(apiurl, multipartFormDataContent).Result; 26                     if (response.StatusCode == System.Net.HttpStatusCode.OK) 27                     { 28                         var result = response.Content.ReadAsStringAsync().Result; 29                         if ((int)response.StatusCode == 200) 30                         { 31                             repath = (upfilePath + filename).Replace("\", "/"); 32                         } 33                     } 34                 } 35                 return repath; 36             } 37             catch (Exception ex) 38             { 39                 return repath; 40             } 41         }

接下来看看在远程cdn服务器上如何接收本地服务器上传过来的文件,实际上跟本地服务上传没多大区别。

创建一个文件上传服务,比如创建一个WebApI服务,创建一个文件上传接口:/api/UpLoad/ReceiveFile,然后将该服务发布到IIS上即可

本地服务的文件上传与远程服务的文件上传(图片上传)

然后客户端请求路径:https://cache.xxxxxx.com:8080/api/UpLoad/ReceiveFile

 1     /// <summary>  2     /// 文件上传服务  3     /// </summary>  4     public class UpLoadController : ApiController  5     {  6         /// <summary>  7         /// 文件接收接口  8         /// </summary>  9         /// <returns></returns> 10         [HttpPost] 11         public HttpResponseMessage ReceiveFile() 12         { 13             HttpResponseMessage response = null; 14             try 15             { 16                 HttpPostedFile file = HttpContext.Current.Request.Files.Get("filedata");           //获取文件流 17                 string getfilepath = HttpContext.Current.Request["filePath"] ?? "\Images\";      //获取保存路径(不包含文件名),默认:\Images\ 18                 var filename = file.FileName;   //获取文件名 19  20                 //保存到本地的路径,~/表示指向上级根目录 21                 string savePath = HttpContext.Current.Server.MapPath("~/" + getfilepath); 22  23                 //创建文件夹 24                 if (!Directory.Exists(savePath)) 25                 { 26                     Directory.CreateDirectory(savePath); 27                 } 28  29                 //保存文件到指定路径下 30                 string saveFilePath = Path.Combine(savePath, filename); 31                 Stream postStream = file.InputStream; 32                 using (FileStream fs = new FileStream(saveFilePath, FileMode.Create)) 33                 { 34                     byte[] new_b = new byte[postStream.Length]; 35                     while (postStream.Read(new_b, 0, new_b.Length) != 0) 36                     { 37                         fs.Write(new_b, 0, new_b.Length); 38                     } 39                     postStream.Close(); 40                     fs.Close(); 41                     fs.Dispose(); 42                 } 43                 response = Request.CreateResponse(HttpStatusCode.OK);  //成功返回200 44             } 45             catch (Exception) 46             { 47                 response = Request.CreateResponse(HttpStatusCode.BadRequest); //返回400 48             } 49             return response; 50         } 51  52     }