微信小程序开发之多图片上传+.NET WebAPI后端服务保存图片资源

简介: 微信小程序开发之多图片上传+.NET WebAPI后端服务保存图片资源

前言:

  最近开发的一个微信小程序项目需要做一个同时选中三张(或者是多张)图片一起上传到服务端,服务端保存图片资源并保存的功能。发现在微信小程序开发中会有很多场景会使用到多图片上传并保存到的功能,所以我把自己总结的一些方法和完整示例写了下来希望能够帮到有需要的同学。

使用技术:

  在这章中将会使用到微信小程序wx.uploadFile(Object object) 和wx.chooseImage(Object object)接口,对图片大小和来源进行上传,后端则使用的.NET WebAPI来接收图片资源文件并保存。

wx.chooseImage() 概述:

  从本地相册选择图片或使用相机拍照,详细了解请阅读微信小程序开发文档(https://developers.weixin.qq.com/miniprogram/dev/api/wx.chooseImage.html?search-key=wx.chooseimage

参数:

属性 类型 默认值 必填 说明
count number 9 最多可以选择的图片张数
sizeType Array.<string> ['original', 'compressed'] 所选的图片的尺寸
sourceType Array.<string> ['album', 'camera'] 选择图片的来源
success function   接口调用成功的回调函数
fail function   接口调用失败的回调函数
complete function   接口调用结束的回调函数(调用成功、失败都会执行)

wx.uploadFile()概述:

  将本地资源上传到服务器。客户端发起一个 HTTPS POST 请求,其中 content-typemultipart/form-data,详细了解请阅读微信小程序开发文档(https://developers.weixin.qq.com/miniprogram/dev/api/wx.uploadFile.html?q=wx.uploadFile)。

参数:

属性 类型 默认值 必填 说明
url string   开发者服务器地址
filePath string   要上传文件资源的路径
name string   文件对应的 key,开发者在服务端可以通过这个 key 获取文件的二进制内容
header Object   HTTP 请求 Header,Header 中不能设置 Referer
formData Object   HTTP 请求中其他额外的 form data
success function   接口调用成功的回调函数
fail function   接口调用失败的回调函数
complete function   接口调用结束的回调函数(调用成功、失败都会执行)

废话不多说,上代码:

小程序页面代码:

<view class='form-s2'>
<view>门店照片(请选择三张)</view>
<view>
<view class="weui-uploader__files" id="uploaderFiles">
<block wx:for="{{files}}" wx:key="*this">
<view class="weui-uploader__file" bindtap="previewImage" id="{{item}}" style='margin-top:11px;'>
<image class="weui-uploader__img" src="{{item}}" mode="aspectFill" />
</view>
</block>
</view>
<view class="weui-uploader__input-box" style='top:11px;'>
<view class="weui-uploader__input" bindtap="chooseImage"></view>
</view>
</view>
</view>

小程序Js代码:

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.picturePath;
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链接列表
})},
})

.NET WebAPI接口服务接收图片资源并保存:

后端使用MultipartMemoryStreamProvider来上传文件,详情如下所示:

using System;
using System.IO;
using System.Net.Http;
using System.Threading.Tasks;
using System.Web.Hosting;
using System.Web.Http;
namespace ShopSite.Controllers
{
    public class FileUploadController : ApiController
    {
        /// <summary>
        /// 图片上传保存
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        public IHttpActionResult PictureUpload()
        {
            try
            {
                var picturePath = "";
                const string fileTypes = "gif,jpg,jpeg,png,bmp";//运行上传的图片文件格式
                var content = Request.Content;//获取或设置 HTTP 消息的内容(当需要获取HTTP信息是会使用到)
                const string tempUploadFiles = "/UploadFile/"; //保存路径
                var newFilePath = DateTime.Now.ToString("yyyy-MM-dd") + "/";
                var memoryStreamProvider = new MultipartMemoryStreamProvider();//获取图片文件流信息
                Task.Run(async () => await Request.Content.ReadAsMultipartAsync(memoryStreamProvider)).Wait();
                foreach (var item in memoryStreamProvider.Contents)
                {
                    if (item.Headers.ContentDisposition.FileName == null) continue;
                    var filename = item.Headers.ContentDisposition.FileName.Replace("\"", "");
                    var file = new FileInfo(filename);
                    //upload fail(判断是否是运行上传的图片格式)
                    if (Array.IndexOf(fileTypes.Split(','), file.Extension.Substring(1).ToLower()) == -1)
                    {
                        return Json(new { code =0,picturePath ="", msg = "不支持上传文件类型" });
                    }
                    //获取后缀
                    var extension = Path.GetExtension(filename);
                    var newFileName = Guid.NewGuid().ToString()+extension;//重命名
                    if (!Directory.Exists(HostingEnvironment.MapPath("/") + tempUploadFiles + newFilePath))
                    {
                        Directory.CreateDirectory(HostingEnvironment.MapPath("/") + tempUploadFiles + newFilePath);
                    }
                    var filePath = Path.Combine(HostingEnvironment.MapPath("/") + tempUploadFiles + newFilePath, newFileName);
                    picturePath=Path.Combine(tempUploadFiles + newFilePath, newFileName);//图片相对路径
                    var result = item.ReadAsStreamAsync().Result;
                    using (var br = new BinaryReader(result))
                    {
                        var data = br.ReadBytes((int)result.Length);
                        File.WriteAllBytes(filePath, data);//保存图片
                    }
                }
                //save successfully
                return Json(new { code = 1, picturePath = picturePath,msg = "图片上传成功~" });
            }
            catch (Exception ex)
            {
                return Json(new { code =0, msg = ex.Message });
            }
        }
    }

效果图展示(美女哟,嘻嘻):


image.png

总结:

 其实做完回过头来想想,无论是微信小程序图片上传还是h5 js图片上传原理其实都是差不多,都是通过content-type 为 multipart/form-data 标识,通过http post将图片资源文件以二进制的编码格式传往后台,然后后台获取对应文件流进行数据图片保存。总结的不够到位,有什么没做好的望各位大佬指点。

相关文章
|
3月前
|
消息中间件 人工智能 Java
抖音微信爆款小游戏大全:免费休闲/竞技/益智/PHP+Java全筏开源开发
本文基于2025年最新行业数据,深入解析抖音/微信爆款小游戏的开发逻辑,重点讲解PHP+Java双引擎架构实战,涵盖技术选型、架构设计、性能优化与开源生态,提供完整开源工具链,助力开发者从理论到落地打造高留存、高并发的小游戏产品。
|
4月前
|
小程序 JavaScript API
uni-halo + 微信小程序开发实录:我的第一个作品诞生记
这篇文章介绍了使用uni-halo框架进行微信小程序开发的过程,包括选择该框架的原因、开发目标以及项目配置和部署的步骤。
190 0
uni-halo + 微信小程序开发实录:我的第一个作品诞生记
|
7月前
|
小程序 前端开发 Android开发
小程序微信分享功能如何开发?开放平台已绑定仍不能使用的问题?-优雅草卓伊凡
小程序微信分享功能如何开发?开放平台已绑定仍不能使用的问题?-优雅草卓伊凡
1497 29
小程序微信分享功能如何开发?开放平台已绑定仍不能使用的问题?-优雅草卓伊凡
|
6月前
|
监控 数据可视化 数据处理
微信养号脚本,全自动插件,AUTOJS开发版
这是一套自动化微信养号工具,包含主脚本`wechat_auto.js`与配置文件`config.json`。主脚本实现自动浏览朋友圈、随机阅读订阅号文章及搜索指定公众号三大功能,支持自定义滚动次数、阅读时长等参数。代码通过随机化操作间隔模拟真实用户行为,具备完善的错误处理和日志记录功能。配套UI模块提供可视化操作界面,可实时监控任务状态与运行日志,便于调整参数设置。控制器部分扩展了批量数据处理能力,如学生信息的增删改查操作,适用于多场景应用。下载地址:https://www.pan38.com/share.php?code=n6cPZ 提取码:8888(仅供学习参考)。
|
8月前
|
监控 前端开发 小程序
陪练,代练,护航,代打小程序源码/前端UNIAPP-VUE2.0开发 后端Thinkphp6管理/具备家政服务的综合型平台
这款APP通过技术创新,将代练、家政、娱乐社交等场景融合,打造“全能型生活服务生态圈”。以代练为切入点,提供模块化代码支持快速搭建平台,结合智能匹配与技能审核机制,拓展家政服务和商业管理功能。技术架构具备高安全性和扩展性,支持多业务复用,如押金冻结、录屏监控等功能跨领域应用。商业模式多元,包括交易抽成、增值服务及广告联名,同时设计跨领域积分体系提升用户粘性,实现生态共生与B端赋能。
813 12
|
8月前
|
小程序 Java 关系型数据库
weixin163基于微信小程序的校园二手交易平台系统设计与开发ssm(文档+源码)_kaic
本文介绍了一款基于微信小程序的校园二手物品交易平台的开发与实现。该平台采用Java语言开发服务端,使用MySQL数据库进行数据存储,前端以微信小程序为载体,支持管理员和学生两种角色操作。管理员可管理用户、商品分类及信息、交易记录等,而学生则能注册登录、发布购买商品、参与交流论坛等。系统设计注重交互性和安全性,通过SSM框架优化开发流程,确保高效稳定运行,满足用户便捷交易的需求,推动校园资源共享与循环利用。
|
JSON 小程序 JavaScript
uni-app开发微信小程序的报错[渲染层错误]排查及解决
uni-app开发微信小程序的报错[渲染层错误]排查及解决
3125 7
|
小程序 JavaScript 前端开发
uni-app开发微信小程序:四大解决方案,轻松应对主包与vendor.js过大打包难题
uni-app开发微信小程序:四大解决方案,轻松应对主包与vendor.js过大打包难题
2794 1
|
小程序 前端开发 测试技术
微信小程序的开发完整流程是什么?
微信小程序的开发完整流程是什么?
2167 7
|
9月前
|
人工智能 自然语言处理 小程序
技术小白如何利用DeepSeek半小时开发微信小程序?
通过通义灵码的“AI程序员”功能,即使没有编程基础也能轻松创建小程序或网页。借助DeepSeek V3和R1满血版模型,用户只需用自然语言描述需求,就能自动生成代码并优化程序。例如,一个文科生仅通过描述需求就成功开发了一款记录日常活动的微信小程序。此外,通义灵码还提供智能问答模式,帮助用户解决开发中的各种问题,极大简化了开发流程,让普通人的开发体验更加顺畅。
2733 11
技术小白如何利用DeepSeek半小时开发微信小程序?