QrCodeApi.cs 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343
  1. #region Apache License Version 2.0
  2. /*----------------------------------------------------------------
  3. Copyright 2019 Jeffrey Su & Suzhou Senparc Network Technology Co.,Ltd.
  4. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
  5. except in compliance with the License. You may obtain a copy of the License at
  6. http://www.apache.org/licenses/LICENSE-2.0
  7. Unless required by applicable law or agreed to in writing, software distributed under the
  8. License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
  9. either express or implied. See the License for the specific language governing permissions
  10. and limitations under the License.
  11. Detail: https://github.com/JeffreySu/WeiXinMPSDK/blob/master/license.md
  12. ----------------------------------------------------------------*/
  13. #endregion Apache License Version 2.0
  14. /*----------------------------------------------------------------
  15. Copyright (C) 2019 Senparc
  16. 文件名:QrCodeAPI.cs
  17. 文件功能描述:二维码接口
  18. 创建标识:Senparc - 20150211
  19. 修改标识:Senparc - 20150303
  20. 修改描述:整理接口
  21. 修改标识:Senparc - 20150312
  22. 修改描述:开放代理请求超时时间
  23. 修改标识:Senparc - 20150623
  24. 修改描述:添加 用字符串类型创建二维码 接口
  25. 修改标识:Senparc - 20160719
  26. 修改描述:增加其接口的异步方法
  27. 修改标识:Senparc - 20160901
  28. 修改描述:v14.3.7 修改Create方法(及对应异步方法),匹配最新的官方文档,删除CreateByStr方法(及对应异步方法)
  29. 修改标识:Senparc - 20170707
  30. 修改描述:v14.5.1 完善异步方法async/await
  31. 修改标识:Senparc - 20170715
  32. 修改描述:v14.5.3 添加 QrCode_ActionName.QR_STR_SCENE
  33. ----------------------------------------------------------------*/
  34. /*
  35. API:http://mp.weixin.qq.com/wiki/index.php?title=%E7%94%9F%E6%88%90%E5%B8%A6%E5%8F%82%E6%95%B0%E7%9A%84%E4%BA%8C%E7%BB%B4%E7%A0%81
  36. */
  37. using System;
  38. using System.IO;
  39. using System.Threading.Tasks;
  40. using Senparc.CO2NET.Extensions;
  41. using Senparc.NeuChar;
  42. using Senparc.Weixin.CommonAPIs;
  43. using Senparc.CO2NET.HttpUtility;
  44. using Senparc.Weixin.MP.AdvancedAPIs.QrCode;
  45. using Senparc.Weixin.MP.CommonAPIs;
  46. namespace Senparc.Weixin.MP.AdvancedAPIs
  47. {
  48. /// <summary>
  49. /// 二维码接口
  50. /// </summary>
  51. public static class QrCodeApi
  52. {
  53. #region 同步方法
  54. /// <summary>
  55. /// 创建二维码
  56. /// </summary>
  57. /// <param name="accessTokenOrAppId">AccessToken或AppId(推荐使用AppId,需要先注册)</param>
  58. /// <param name="expireSeconds">临时二维码有效时间,以秒为单位。最大不超过2592000(即30天),此字段如果不填,则默认有效期为30秒,永久二维码将忽略此参数</param>
  59. /// <param name="sceneId">场景值ID,临时二维码时为32位非0整型,永久二维码时最大值为100000(目前参数只支持1--100000)</param>
  60. /// <param name="sceneStr">场景字符串,字符串类型,长度限制为1到64,仅actionName为QR_LIMIT_STR_SCENE时有效</param>
  61. /// <param name="timeOut">代理请求超时时间(毫秒)</param>
  62. /// <param name="actionName">二维码类型,当actionName为QR_LIMIT_STR_SCENE时,sceneId会被忽略</param>
  63. /// <returns></returns>
  64. [ApiBind(NeuChar.PlatformType.WeChat_OfficialAccount, "QrCodeApi.Create", true)]
  65. public static CreateQrCodeResult Create(string accessTokenOrAppId, int expireSeconds, int sceneId, QrCode_ActionName actionName, string sceneStr = null, int timeOut = Config.TIME_OUT)
  66. {
  67. return ApiHandlerWapper.TryCommonApi(accessToken =>
  68. {
  69. var urlFormat = Config.ApiMpHost + "/cgi-bin/qrcode/create?access_token={0}";
  70. object data = null;
  71. switch (actionName)
  72. {
  73. case QrCode_ActionName.QR_SCENE:
  74. data = new
  75. {
  76. expire_seconds = expireSeconds,
  77. action_name = "QR_SCENE",
  78. action_info = new
  79. {
  80. scene = new
  81. {
  82. scene_id = sceneId
  83. }
  84. }
  85. };
  86. break;
  87. case QrCode_ActionName.QR_LIMIT_SCENE:
  88. data = new
  89. {
  90. action_name = "QR_LIMIT_SCENE",
  91. action_info = new
  92. {
  93. scene = new
  94. {
  95. scene_id = sceneId
  96. }
  97. }
  98. };
  99. break;
  100. case QrCode_ActionName.QR_LIMIT_STR_SCENE:
  101. data = new
  102. {
  103. action_name = "QR_LIMIT_STR_SCENE",
  104. action_info = new
  105. {
  106. scene = new
  107. {
  108. scene_str = sceneStr
  109. }
  110. }
  111. };
  112. break;
  113. case QrCode_ActionName.QR_STR_SCENE:
  114. data = new
  115. {
  116. expire_seconds = expireSeconds,
  117. action_name = "QR_STR_SCENE",
  118. action_info = new
  119. {
  120. scene = new
  121. {
  122. scene_str = sceneStr
  123. }
  124. }
  125. };
  126. break;
  127. default:
  128. //throw new ArgumentOutOfRangeException(nameof(actionName), actionName, null);
  129. throw new ArgumentOutOfRangeException(actionName.GetType().Name, actionName, null);
  130. }
  131. return CommonJsonSend.Send<CreateQrCodeResult>(accessToken, urlFormat, data, timeOut: timeOut);
  132. }, accessTokenOrAppId);
  133. }
  134. ///// <summary>
  135. ///// 用字符串类型创建二维码(永久)
  136. ///// </summary>
  137. ///// <param name="accessTokenOrAppId">AccessToken或AppId(推荐使用AppId,需要先注册)</param>
  138. ///// <param name="sceneStr">场景值ID(字符串形式的ID),字符串类型,长度限制为1到64,仅永久二维码支持此字段</param>
  139. ///// <param name="timeOut"></param>
  140. ///// <returns></returns>
  141. //public static CreateQrCodeResult CreateByStr(string accessTokenOrAppId, string sceneStr, int timeOut = Config.TIME_OUT)
  142. //{
  143. // return ApiHandlerWapper.TryCommonApi(accessToken =>
  144. // {
  145. // var urlFormat = Config.ApiMpHost + "/cgi-bin/qrcode/create?access_token={0}";
  146. // var data = new
  147. // {
  148. // action_name = "QR_LIMIT_STR_SCENE", action_info = new
  149. // {
  150. // scene = new
  151. // {
  152. // scene_str = sceneStr
  153. // }
  154. // }
  155. // };
  156. // return CommonJsonSend.Send<CreateQrCodeResult>(accessToken, urlFormat, data, timeOut: timeOut);
  157. // }, accessTokenOrAppId);
  158. //}
  159. /*此接口无异步方法*/
  160. /// <summary>
  161. /// 获取下载二维码的地址
  162. /// </summary>
  163. /// <param name="ticket"></param>
  164. /// <returns></returns>
  165. [ApiBind(NeuChar.PlatformType.WeChat_OfficialAccount, "QrCodeApi.GetShowQrCodeUrl", true)]
  166. public static string GetShowQrCodeUrl(string ticket)
  167. {
  168. var urlFormat = "https://mp.weixin.qq.com/cgi-bin/showqrcode?ticket={0}";
  169. return string.Format(urlFormat, ticket.AsUrlData());
  170. }
  171. /// <summary>
  172. /// 获取二维码(不需要AccessToken)
  173. /// 错误情况下(如ticket非法)返回HTTP错误码404。
  174. /// </summary>
  175. /// <param name="ticket"></param>
  176. /// <param name="stream"></param>
  177. [ApiBind(NeuChar.PlatformType.WeChat_OfficialAccount, "QrCodeApi.ShowQrCode", true)]
  178. public static void ShowQrCode(string ticket, Stream stream)
  179. {
  180. var url = GetShowQrCodeUrl(ticket);
  181. Get.Download(url, stream);
  182. }
  183. #endregion
  184. #if !NET35 && !NET40
  185. #region 异步方法
  186. /// <summary>
  187. /// 创建二维码
  188. /// </summary>
  189. /// <param name="accessTokenOrAppId">AccessToken或AppId(推荐使用AppId,需要先注册)</param>
  190. /// <param name="expireSeconds">临时二维码有效时间,以秒为单位。最大不超过2592000(即30天),此字段如果不填,则默认有效期为30秒,永久二维码将忽略此参数</param>
  191. /// <param name="sceneId">场景值ID,临时二维码时为32位非0整型,永久二维码时最大值为100000(目前参数只支持1--100000)</param>
  192. /// <param name="sceneStr">场景字符串,字符串类型,长度限制为1到64,仅actionName为QR_LIMIT_STR_SCENE时有效</param>
  193. /// <param name="timeOut">代理请求超时时间(毫秒)</param>
  194. /// <param name="actionName">二维码类型,当actionName为QR_LIMIT_STR_SCENE时,sceneId会被忽略</param>
  195. /// <returns></returns>
  196. [ApiBind(NeuChar.PlatformType.WeChat_OfficialAccount, "QrCodeApi.CreateAsync", true)]
  197. public static async Task<CreateQrCodeResult> CreateAsync(string accessTokenOrAppId, int expireSeconds, int sceneId, QrCode_ActionName actionName, string sceneStr = null, int timeOut = Config.TIME_OUT)
  198. {
  199. return await ApiHandlerWapper.TryCommonApiAsync(async accessToken =>
  200. {
  201. var urlFormat = Config.ApiMpHost + "/cgi-bin/qrcode/create?access_token={0}";
  202. object data = null;
  203. switch (actionName)
  204. {
  205. case QrCode_ActionName.QR_SCENE:
  206. data = new
  207. {
  208. expire_seconds = expireSeconds,
  209. action_name = "QR_SCENE",
  210. action_info = new
  211. {
  212. scene = new
  213. {
  214. scene_id = sceneId
  215. }
  216. }
  217. };
  218. break;
  219. case QrCode_ActionName.QR_LIMIT_SCENE:
  220. data = new
  221. {
  222. action_name = "QR_LIMIT_SCENE",
  223. action_info = new
  224. {
  225. scene = new
  226. {
  227. scene_id = sceneId
  228. }
  229. }
  230. };
  231. break;
  232. case QrCode_ActionName.QR_LIMIT_STR_SCENE:
  233. data = new
  234. {
  235. action_name = "QR_LIMIT_STR_SCENE",
  236. action_info = new
  237. {
  238. scene = new
  239. {
  240. scene_str = sceneStr
  241. }
  242. }
  243. };
  244. break;
  245. case QrCode_ActionName.QR_STR_SCENE:
  246. data = new
  247. {
  248. expire_seconds = expireSeconds,
  249. action_name = "QR_STR_SCENE",
  250. action_info = new
  251. {
  252. scene = new
  253. {
  254. scene_str = sceneStr
  255. }
  256. }
  257. };
  258. break;
  259. default:
  260. //throw new ArgumentOutOfRangeException(nameof(actionName), actionName, null);
  261. throw new ArgumentOutOfRangeException(actionName.GetType().Name, actionName, null);
  262. }
  263. return await Senparc.Weixin.CommonAPIs.CommonJsonSend.SendAsync<CreateQrCodeResult>(accessToken, urlFormat, data, timeOut: timeOut);
  264. }, accessTokenOrAppId);
  265. }
  266. ///// <summary>
  267. ///// 【异步方法】用字符串类型创建二维码
  268. ///// </summary>
  269. ///// <param name="accessTokenOrAppId">AccessToken或AppId(推荐使用AppId,需要先注册)</param>
  270. ///// <param name="sceneStr">场景值ID(字符串形式的ID),字符串类型,长度限制为1到64,仅永久二维码支持此字段</param>
  271. ///// <param name="timeOut"></param>
  272. ///// <returns></returns>
  273. //public static async Task<CreateQrCodeResult> CreateByStrAsync(string accessTokenOrAppId, string sceneStr, int timeOut = Config.TIME_OUT)
  274. //{
  275. // return await ApiHandlerWapper.TryCommonApiAsync(async accessToken =>
  276. // {
  277. // var urlFormat = Config.ApiMpHost + "/cgi-bin/qrcode/create?access_token={0}";
  278. // var data = new
  279. // {
  280. // action_name = "QR_LIMIT_STR_SCENE", action_info = new
  281. // {
  282. // scene = new
  283. // {
  284. // scene_str = sceneStr
  285. // }
  286. // }
  287. // };
  288. // return await Senparc.Weixin.CommonAPIs.CommonJsonSend.SendAsync<CreateQrCodeResult>(accessToken, urlFormat, data, timeOut: timeOut);
  289. // }, accessTokenOrAppId);
  290. //}
  291. /// <summary>
  292. ///【异步方法】 获取二维码(不需要AccessToken)
  293. /// 错误情况下(如ticket非法)返回HTTP错误码404。
  294. /// </summary>
  295. /// <param name="ticket"></param>
  296. /// <param name="stream"></param>
  297. [ApiBind(NeuChar.PlatformType.WeChat_OfficialAccount, "QrCodeApi.ShowQrCodeAsync", true)]
  298. public static async Task ShowQrCodeAsync(string ticket, Stream stream)
  299. {
  300. var url = GetShowQrCodeUrl(ticket);
  301. await Get.DownloadAsync(url, stream);
  302. }
  303. #endregion
  304. #endif
  305. }
  306. }