微信小程序開發之多圖片上傳+.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-type 為 multipart/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 });
            }
        }
    }
}

 

效果圖展示(美女喲,嘻嘻):

總結:

  其實做完回過頭來想想,無論是微信小程序圖片上傳還是h5 js圖片上傳原理其實都是差不多,都是通過content-type 為 multipart/form-data 標識,通過http post將圖片資源文件以二進制的編碼格式傳往后台,然后后台獲取對應文件流進行數據圖片保存。總結的不夠到位,有什么沒做好的望各位大佬指點。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM