在开发微信小程序的过程中经常会遇到这样的需求,需要做一个小程序同时选中三张图片一起上传到服务端,后端使用的.NET WEBAPI接收数据保存。如何进行操作?春哥团队技术大东分享如下:
使用技术:将会使用到微信小程序wx.uploadFile(Object object) 和wx.chooseImage(Object object)接口,对图片大小和来源进行上传。
wx.chooseImage() 概述:
从本地相册选择图片或使用相机拍照,详细了解请阅读微信小程序开发文档(https://developers.weixin.qq.com/miniprogram/dev/api/wx.chooseImage.html?search-key=wx.chooseimage)
参数
Object object
wx.uploadFile()概述:
将本地资源上传到服务器。客户端发起一个 HTTPS POST 请求,其中 content-type 为 multipart/form-data,详细了解请阅读微信小程序开发文档(https://developers.weixin.qq.com/miniprogram/dev/api/wx.uploadFile.html?q=wx.uploadFile)。
参数

废话不多说,上代码:
.Wxml code:
class='form-s2'>门店照片(请选择三张)class="weui-uploader__files" id="uploaderFiles">wx:for="{{files}}" wx:key="*this">class="weui-uploader__file" bindtap="previewImage" id="{{item}}" style='margin-top:11px;'>class="weui-uploader__img" src="{{item}}" mode="aspectFill" />class="weui-uploader__input-box" style='top:11px;'>class="weui-uploader__input" bindtap="chooseImage">
.Js code:
Page({/*** 页面的初始数据*/data:{files: [], //门店图片信息,数组图片保存作为数据源},,/*** 多图片上传*/chooseImage: function(e) {var that = this;if (that.data.files.length > 2) {resource.notishi("抱歉最多只允许上传三张图片哟~");return false;}wx.chooseImage({count: 3, //默认9张,这里设置三张sizeType: ['original', 'compressed'], // 可以指定是原图还是压缩图,默认二者都有sourceType: ['album', 'camera'], // 可以指定来源是相册还是相机,默认二者都有success: function(res) {wx.showLoading({title: '上传中,请稍等...',})// 返回选定照片的本地文件路径列表,tempFilePath可以作为img标签的src属性显示图片var tempFilePaths = res.tempFilePaths;//多图片上传,tempFilePaths本地图片地址为一个数组,遍历调用服务器图片上传接口即可实现多图保存for (var i = 0; i < tempFilePaths.length; i++) {console.log('图片地址名称' + tempFilePaths[i]);wx.uploadFile({url: app.globalData.hostUrl + "/api/PictureUpload/Upload", //此处为实际接口地址filePath: tempFilePaths[i], //获取图片路径header: {'content-type': 'multipart/form-data'},name: 'upload',success: function(res) {wx.hideLoading();let Result = JSON.parse(res.data);console.log(Result);//接收返回来的服务器图片地址if (Result.code == 1) {let picurl = app.globalData.hostUrl + Result.picurl;console.log(picurl);that.setData({files: that.data.files.concat(picurl)});} else {resource.notishi("网络异常,请稍后再试");}},fail: function(res) {wx.hideLoading()wx.showToast({title: '上传失败,请重新上传',icon: 'none',duration: 2000})},})}}})},//图片预览previewImage: function(e) {wx.previewImage({current: e.currentTarget.id, // 当前显示图片的http链接urls: this.data.files // 需要预览的图片http链接列表})},})
后端图片接收保存 code(.Net WEBAPI)
////// 图片上传保存//////[HttpPost]public IHttpActionResult Upload(){try{var content = Request.Content;//获取http设置的消息和内容var tempUploadFiles = "/Images/Wechatimages/";//保存路径var newFileName = "";string filePath = "";string extname = "";string returnurl = "";var sp = new MultipartMemoryStreamProvider();Task.Run(async () => await Request.Content.ReadAsMultipartAsync(sp)).Wait();foreach (var item in sp.Contents){if (item.Headers.ContentDisposition.FileName != null){var filename = item.Headers.ContentDisposition.FileName.Replace("\"", "");FileInfo file = new FileInfo(filename);string fileTypes = "gif,jpg,jpeg,png,bmp";if (Array.IndexOf(fileTypes.Split(','), file.Extension.Substring(1).ToLower()) == -1){throw new ApplicationException("不支持上传文件类型");}//获取后缀extname = System.IO.Path.GetExtension(filename);//获取文件的拓展名称newFileName = Guid.NewGuid().ToString().Substring(0, 6) + extname;string newFilePath = DateTime.Now.ToString("yyyy-MM-dd") + "/";if (!Directory.Exists(HostingEnvironment.MapPath("/") + tempUploadFiles + newFilePath)){Directory.CreateDirectory(HostingEnvironment.MapPath("/") + tempUploadFiles + newFilePath);}filePath = Path.Combine(HostingEnvironment.MapPath("/") + tempUploadFiles + newFilePath, newFileName);returnurl = Path.Combine(tempUploadFiles + newFilePath, newFileName);//图片相对路径var ms = item.ReadAsStreamAsync().Result;using (var br = new BinaryReader(ms)){var data = br.ReadBytes((int)ms.Length);File.WriteAllBytes(filePath, data);//保存图片}}}return Json(new {code=1,picurl= returnurl,msg="success" }) ;}catch (Exception ex){return Json(new { code =0,msg=ex.Message});}}
总结:
其实做完回过头来想想,无论是微信小程序图片上传还是html页面图片上传原理其实都是差不多,都是通过content-type 为 multipart/form-data 标识,通过http post将图片资源文件以二进制的编码格式传往后台,然后后台获取对应文件流进行数据图片保存。总结的不够到位,有什么没做好的望各位大佬指点。



