微信图片上传接口地址:https://api.mch.weixin.qq.com/v3/merchant/media/upload

1、上传方法

 1 using HttpHandlerDemo;
2 using Newtonsoft.Json;
3 using System;
4 using System.Collections.Generic;
5 using System.IO;
6 using System.Linq;
7 using System.Net;
8 using System.Net.Http;
9 using System.Net.Http.Headers;
10 using System.Security.Cryptography;
11 using System.Text;
12 using HttpHandler = Lib.HttpHandler;
13
14 namespace API
15 {
16 public class Helper
17 {
18 public static string UploadImg(string b64)
19 {
20 byte[] data = Convert.FromBase64String(b64);
21 //证书本地路径
22 string certPath = @"***";
23 //证书秘钥
24 string certPwd = "***";
25 //商户号
26 string mchid = "***";
27 //证书编号
28 string serialNo = "***";
29 string boundary = string.Format("--{0}", DateTime.Now.Ticks.ToString("x"));
30 var sha256 = Sha256(data);
31 var meta = new
32 {
33 sha256 = sha256,
34 filename = Guid.NewGuid().ToString().Replace("-", "") + ".png"
35 };
36 var json = JsonConvert.SerializeObject(meta);
37 var httpHandler = new HttpHandler(mchid, serialNo, certPath, certPwd, json);
38 HttpClient client = new HttpClient(httpHandler);
39 using (var content = new MultipartFormDataContent(boundary))
40 {
41 content.Headers.ContentType = MediaTypeHeaderValue.Parse("multipart/form-data"); //这里必须添加
42 content.Add(new StringContent(json, Encoding.UTF8, "application/json"), "\"meta\""); //这里主要必须要双引号
43
44 var byteArrayContent = new ByteArrayContent(data);
45 byteArrayContent.Headers.ContentType = new MediaTypeHeaderValue("image/jpg");
46 content.Add(byteArrayContent, "\"file\"", "\"" + meta.filename + "\""); //这里主要必须要双引号
47 try
48 {
49 using (var response = client.PostAsync("https://api.mch.weixin.qq.com/v3/merchant/media/upload", content)) //上传
50 using (var responseContent = response.Result.Content)
51 {
52 string responseBody = responseContent.ReadAsStringAsync().Result;
53 var dic = Newtonsoft.Json.Linq.JObject.Parse(responseBody);
54 return dic["media_id"].ToString();
55 }
56 }
57 catch (Exception e)
58 {
59 return null;
60 }
61
62
63 }
64 }
65
66 public static string Sha256(byte[] bytes)
67 {
68 byte[] hash = SHA256Managed.Create().ComputeHash(bytes);
69 StringBuilder builder = new StringBuilder();
70 for (int i = 0; i < hash.Length; i++)
71 {
72 builder.Append(hash[i].ToString("X2"));
73 }
74 return builder.ToString();
75 }
76
77 }
78 }

2、Lib.HttpHandler代码

  1 using System;
2 using System.Collections.Generic;
3 using System.IO;
4 using System.Net.Http;
5 using System.Net.Http.Headers;
6 using System.Security.Authentication;
7 using System.Security.Cryptography;
8 using System.Security.Cryptography.X509Certificates;
9 using System.Text;
10 using System.Threading;
11 using System.Threading.Tasks;
12
13 namespace Lib
14 {
15 /// <summary>
16 /// 头文件
17 /// </summary>
18 public class HttpHandler : DelegatingHandler
19 {
20 private readonly string merchantId;
21 private readonly string serialNo;
22 private readonly string certPath;
23 private readonly string certPwd;
24 private readonly string json;
25 /// <summary>
26 /// 构造方法
27 /// </summary>
28 /// <param name="merchantId">商户号</param>
29 /// <param name="merchantSerialNo">证书序列号</param>
30 /// <param name="certPath">证书路径</param>
31 /// <param name="certPwd">证书秘钥</param>
32 /// <param name="json">签名json数据,默认不需要传入,获取body内容,如传入签名传入参数上传图片时需传入</param>
33 public HttpHandler(string merchantId, string merchantSerialNo, string certPath, string certPwd, string json = "")
34 {
35
36 HttpClientHandler handler = new HttpClientHandler();
37 handler.ClientCertificateOptions = ClientCertificateOption.Manual;
38 handler.SslProtocols = SslProtocols.Tls12;
39 try
40 {
41 handler.ClientCertificates.Add(new X509Certificate2(certPath, certPwd,
42 X509KeyStorageFlags.PersistKeySet | X509KeyStorageFlags.MachineKeySet));
43 }
44 catch (Exception e)
45 {
46 throw new Exception("ca err(证书错误)");
47 }
48 handler.SslProtocols = SslProtocols.Tls12 | SslProtocols.Tls11 | SslProtocols.Tls;
49 handler.ServerCertificateCustomValidationCallback = (message, cert, chain, errors) => true;
50 InnerHandler = handler;
51 this.merchantId = merchantId;
52 this.serialNo = merchantSerialNo;
53 this.certPath = certPath;
54 this.certPwd = certPwd;
55 this.json = json;
56 }
57
58 protected async override Task<HttpResponseMessage> SendAsync(
59 HttpRequestMessage request,
60 CancellationToken cancellationToken)
61 {
62 var auth = await BuildAuthAsync(request);
63 string value = $"WECHATPAY2-SHA256-RSA2048 {auth}";
64 request.Headers.Add("Authorization", value);
65 request.Headers.Add("user-agent", "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/36.0.1985.143 Safari/537.36");
66 MediaTypeWithQualityHeaderValue mediaTypeWithQualityHeader = new MediaTypeWithQualityHeaderValue("application/json");
67 request.Headers.Accept.Add(mediaTypeWithQualityHeader);
68 request.Headers.AcceptCharset.Add(new StringWithQualityHeaderValue("utf-8"));
69 return await base.SendAsync(request, cancellationToken);
70 }
71
72 protected async Task<string> BuildAuthAsync(HttpRequestMessage request)
73 {
74 string method = request.Method.ToString();
75 string body = "";
76 if (method == "POST" || method == "PUT" || method == "PATCH")
77 {
78 if (!string.IsNullOrEmpty(json))
79 body = json;
80 else
81 {
82 var content = request.Content;
83 body = await content.ReadAsStringAsync();
84 }
85 }
86 string uri = request.RequestUri.PathAndQuery;
87 var timestamp = DateTimeOffset.Now.ToUnixTimeSeconds();
88 string nonce = Guid.NewGuid().ToString("n");
89 string message = $"{method}\n{uri}\n{timestamp}\n{nonce}\n{body}\n";
90
91 string signature = Sign(message);
92 return $"mchid=\"{merchantId}\",nonce_str=\"{nonce}\",timestamp=\"{timestamp}\",serial_no=\"{serialNo}\",signature=\"{signature}\"";
93 }
94
95 //SHA256withRSA
96 public string Sign(string str)
97 {
98 byte[] bt = Encoding.GetEncoding("utf-8").GetBytes(str);
99 var sha256 = new SHA256CryptoServiceProvider();
100 byte[] rgbHash = sha256.ComputeHash(bt);
101
102 try
103 {
104 var rsa = GetPrivateKey();
105 var key = new RSACryptoServiceProvider();
106 var paras = rsa.ExportParameters(true);
107 key.ImportParameters(paras);
108 RSAPKCS1SignatureFormatter formatter = new RSAPKCS1SignatureFormatter(key);
109 formatter.SetHashAlgorithm("SHA256");
110 byte[] inArray = formatter.CreateSignature(rgbHash);
111 return Convert.ToBase64String(inArray);
112 }
113 catch (Exception e)
114 {
115 return e.Message;
116 }
117 }
118
119 private RSACryptoServiceProvider GetPrivateKey()
120 {
121 var pc = new X509Certificate2(certPath, certPwd, X509KeyStorageFlags.Exportable | X509KeyStorageFlags.MachineKeySet);
122 return (RSACryptoServiceProvider)pc.PrivateKey;
123 }
124
125 }
126 }

仅此记录一下

微信支付特约商户进件中base64格式图片上传的更多相关文章

  1. Aps.net中基于bootstrapt图片上传插件的应用

    Aps.net中基于bootstrapt图片上传插件的应用 在最近的项目中需要使用一个图片上传的功能,而且是多张图片同时上传到服务器的文件夹中,将图片路径存放在数据库中.为了外观好看使用了bootst ...

  2. 从web编辑器 UEditor 中单独提取图片上传,包含多图片单图片上传以及在线涂鸦功能

    UEditor是由百度web前端研发部开发所见即所得富文本web编辑器,具有轻量,可定制,注重用户体验等特点,开源基于MIT协议,允许自由使用和修改代码.(抄的...) UEditor是非常好用的富文 ...

  3. ssm项目中KindEditor的图片上传插件,浏览器兼容性问题

    解决办法: 原因:使用@ResponseBody注解返回java对象,在浏览器中是Content-Type:application/json;charset=UTF-8 我们需要返回字符串(Strin ...

  4. hybird app项目实例:安卓webview中HTML5拍照图片上传

    应用的平台环境:安卓webview: 涉及的技术点: (1) <input type="file" > :在开发中,安卓webview默认点击无法调用文件选择与相机拍照 ...

  5. PHP base64多图片上传

    // 多图片上传,base64 public function upload_multi() { $pic = $_POST['pic']; if (!$pic) { $this->json-& ...

  6. Django中怎么做图片上传--图片展示

    1.首先是html页面的form表单的三大属性,action是提交到哪,method是提交方式,enctype只要有图片上传就要加这个属性 Django框架自带csrf_token ,所以需要在前端页 ...

  7. MVC 中使用kindEditor 图片上传在IE 上进行上传出现的问题

    在IE 上使用KindEditor 进行单张图片上传的时候会出现一个下载安全警告,这样将会造成图片上传失败,出现的错误页面:

  8. 在SSM框架中如何将图片上传到数据库中

    今天我们来看看SSM中如何将图片转换成二进制,最后传入到自己的数据库中,好了,废话不多说,我们开始今天的学习,我这里用的编辑器是IDEA 1.导入图片上传需要的jar依赖包 1 <depende ...

  9. html5 图片转为base64格式异步上传

    因为有这个需求(移动端),所以就研究了一下,发现还挺不错的.这个主要是用了html5的API,不需要其他的JS插件,不过只有支持html5的浏览器才行,就现在而言应该大部份都支持的.<!DOCT ...

随机推荐

  1. Codeforces Global Round 11 A~D题解

    A.Avoiding Zero 题目链接:https://codeforces.ml/contest/1427 题目大意:给定一个数组a1,a2...,an,要求找出一个a重排后的数组b1,b2,.. ...

  2. js 正则表达式 判断val是不是整数

    function isIntNum(val){ var regPos = / ^\d+$/; // 非负整数 // var regNeg = /^\-[1-9][0-9]*$/; // 负整数 if( ...

  3. Linux_centOS_5.7_64下如何安装jdk1.8&mysql

    本文主要介绍的是如何是Linux环境下安装JDK的,因为Linux环境下,很多时候也离不开Java的,下面笔者就和大家一起分享如何jdk1.8的过程吧. JDK安装 环境 操作系统:Centos7_6 ...

  4. 多测师讲解python _函数中变量_高级讲师肖sir

    定义的函数内部的变量名如果是第一次出现, 且在=符号前,那么就可以认为是 被定义为局部变量.在这种情况下,不论全局变量中是否用到该变量名,函数中 使用的都是局部变量.例如: num=100 #全局变量 ...

  5. k8s集群,使用pvc方式实现数据持久化存储

    环境: 系统 华为openEulerOS(CentOS7) k8s版本 1.17.3 master 192.168.1.244 node1 192.168.1.245 介绍: 在Kubernetes中 ...

  6. cmake引入三方库

    目录结构 . |-- cmake | |-- CompilerSettings.cmake | |-- Options.cmake | `-- ProjectJsonCpp.cmake |-- CMa ...

  7. 闭嘴,给你一个数!1分钟,学完C语言指针,不扎手只扎心的针!

    序言 指针是C语言学习者绕不过的一道坎,也是C语言学习者不得绕过的一道坎.辨别一个人C语言学的好赖就看他对指针的理解怎么样.指针内容也是工作面试经常问到的问题.本文将带你重新认识那个绊倒你的指针,以解 ...

  8. centos8平台使用parted管理分区

    一,parted的用途 parted是GNU发布的强大的分区工具, parted命令可以划分单个分区大于2T的GPT格式的分区,也可以划分普通的MBR分区. 因为fdisk命令对于大于2T的分区无法划 ...

  9. Archery安装教程

    一. CentOS设置 1. 更换阿里源 curl -o /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos ...

  10. Linux用户和组管理命令-用户删除userdel

    删除用户 userdel 可删除Linux 用户 格式: userdel [OPTION]... Login 常见选项: -f, --force 强制 -r, --remove 删除用户家目录和邮箱 ...