DefaultAopClient.cs 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242
  1. using System;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4. using System.Threading.Tasks;
  5. using Aop.Api.Parser;
  6. using Aop.Api.Request;
  7. using Aop.Api.Util;
  8. namespace Aop.Api
  9. {
  10. /// <summary>
  11. /// AOP客户端。
  12. /// </summary>
  13. public class DefaultAopClient : IAopClient
  14. {
  15. public const string APP_ID = "app_id";
  16. public const string FORMAT = "format";
  17. public const string METHOD = "method";
  18. public const string TIMESTAMP = "timestamp";
  19. public const string VERSION = "version";
  20. public const string SIGN_TYPE = "sign_type";
  21. public const string ACCESS_TOKEN = "auth_token";
  22. public const string SIGN = "sign";
  23. public const string TERMINAL_TYPE = "terminal_type";
  24. public const string TERMINAL_INFO = "terminal_info";
  25. public const string PROD_CODE = "prod_code";
  26. public const string NOTIFY_URL = "notify_url";
  27. public const string CHARSET = "charset";
  28. private string version;
  29. private string format;
  30. private string serverUrl;
  31. private string appId;
  32. private string privateKeyPem;
  33. private string signType = "RSA";
  34. private string charset;
  35. private string alipayPublicKey;
  36. private WebUtils webUtils;
  37. //public string PrivateKeyPem
  38. //{
  39. // get { return privateKeyPem; }
  40. // set { privateKeyPem = value; }
  41. //}
  42. //public string AlipayPublicKey
  43. //{
  44. // get { return alipayPublicKey; }
  45. // set { alipayPublicKey = value; }
  46. //}
  47. public string Version
  48. {
  49. get { return version != null ? version : "1.0"; }
  50. set { version = value; }
  51. }
  52. public string Format
  53. {
  54. get { return format != null ? format : "json"; }
  55. set { format = value; }
  56. }
  57. public string AppId
  58. {
  59. get { return appId; }
  60. set { appId = value; }
  61. }
  62. #region DefaultAopClient Constructors
  63. public DefaultAopClient(string serverUrl, string appId, string privateKeyPem)
  64. {
  65. this.appId = appId;
  66. this.privateKeyPem = privateKeyPem;
  67. this.serverUrl = serverUrl;
  68. this.webUtils = new WebUtils();
  69. }
  70. public DefaultAopClient(string serverUrl, string appId, string privateKeyPem, string format)
  71. {
  72. this.appId = appId;
  73. this.privateKeyPem = privateKeyPem;
  74. this.serverUrl = serverUrl;
  75. this.format = format;
  76. this.webUtils = new WebUtils();
  77. }
  78. public DefaultAopClient(string serverUrl, string appId, string privateKeyPem, string format, string charset)
  79. : this(serverUrl, appId, privateKeyPem, format)
  80. {
  81. this.charset = charset;
  82. }
  83. public DefaultAopClient(string serverUrl, string appId, string privateKeyPem, string format, string version, string signType)
  84. : this(serverUrl, appId, privateKeyPem)
  85. {
  86. this.format = format;
  87. this.version = version;
  88. this.signType = signType;
  89. }
  90. public DefaultAopClient(string serverUrl, string appId, string privateKeyPem, string format, string version, string signType, string alipayPulicKey)
  91. : this(serverUrl, appId, privateKeyPem, format, version, signType)
  92. {
  93. this.alipayPublicKey = alipayPulicKey;
  94. }
  95. public DefaultAopClient(string serverUrl, string appId, string privateKeyPem, string format, string version, string signType, string alipayPulicKey, string charset)
  96. : this(serverUrl, appId, privateKeyPem, format, version, signType, alipayPulicKey)
  97. {
  98. this.charset = charset;
  99. }
  100. public void SetTimeout(int timeout)
  101. {
  102. webUtils.Timeout = timeout;
  103. }
  104. #endregion
  105. #region IAopClient Members
  106. public async Task<T> Execute<T>(IAopRequest<T> request) where T : AopResponse
  107. {
  108. return await Execute<T>(request, null);
  109. }
  110. public async Task<T> Execute<T>(IAopRequest<T> request, string accessToken) where T : AopResponse
  111. {
  112. if (string.IsNullOrEmpty(this.charset))
  113. {
  114. this.charset = "utf-8";
  115. }
  116. string apiVersion = null;
  117. if (!string.IsNullOrEmpty(request.GetApiVersion()))
  118. {
  119. apiVersion = request.GetApiVersion();
  120. }
  121. else
  122. {
  123. apiVersion = Version;
  124. }
  125. // 添加协议级请求参数
  126. AopDictionary txtParams = new AopDictionary(request.GetParameters());
  127. txtParams.Add(METHOD, request.GetApiName());
  128. txtParams.Add(VERSION, apiVersion);
  129. txtParams.Add(APP_ID, appId);
  130. txtParams.Add(FORMAT, format);
  131. txtParams.Add(TIMESTAMP, DateTime.Now);
  132. txtParams.Add(ACCESS_TOKEN, accessToken);
  133. txtParams.Add(SIGN_TYPE, signType);
  134. txtParams.Add(TERMINAL_TYPE, request.GetTerminalType());
  135. txtParams.Add(TERMINAL_INFO, request.GetTerminalInfo());
  136. txtParams.Add(PROD_CODE, request.GetProdCode());
  137. txtParams.Add(NOTIFY_URL, request.GetNotifyUrl());
  138. txtParams.Add(CHARSET, charset);
  139. // 添加签名参数
  140. txtParams.Add(SIGN, AopUtils.SignAopRequest(txtParams, privateKeyPem, charset));
  141. // 是否需要上传文件
  142. string body;
  143. if (request is IAopUploadRequest<T>)
  144. {
  145. IAopUploadRequest<T> uRequest = (IAopUploadRequest<T>)request;
  146. IDictionary<string, FileItem> fileParams = AopUtils.CleanupDictionary(uRequest.GetFileParameters());
  147. body = await webUtils.DoPost(this.serverUrl + "?" + CHARSET + "=" + this.charset, txtParams, fileParams, this.charset);
  148. }
  149. else
  150. {
  151. body = await webUtils.DoPost(this.serverUrl + "?" + CHARSET + "=" + this.charset, txtParams, this.charset);
  152. }
  153. T rsp = null;
  154. IAopParser<T> parser = null;
  155. if ("xml".Equals(format))
  156. {
  157. parser = new AopXmlParser<T>();
  158. rsp = parser.Parse(body, charset);
  159. }
  160. else
  161. {
  162. parser = new AopJsonParser<T>();
  163. rsp = parser.Parse(body, charset);
  164. }
  165. CheckResponseSign(request, rsp, parser, alipayPublicKey, this.charset);
  166. return rsp;
  167. }
  168. public static void CheckResponseSign<T>(IAopRequest<T> request, T tRsp, IAopParser<T> parser, string alipayPublicKey, string charset) where T : AopResponse
  169. {
  170. if (string.IsNullOrEmpty(alipayPublicKey) || string.IsNullOrEmpty(charset))
  171. {
  172. return;
  173. }
  174. SignItem signItem = parser.GetSignItem(request, tRsp);
  175. if (signItem == null)
  176. {
  177. throw new AopException("sign check fail: Body is Empty!");
  178. }
  179. if (!tRsp.IsError ||
  180. (tRsp.IsError && !string.IsNullOrEmpty(signItem.Sign)))
  181. {
  182. bool rsaCheckContent = AlipaySignature.RSACheckContent(signItem.SignSourceDate, signItem.Sign, alipayPublicKey, charset);
  183. if (!rsaCheckContent)
  184. {
  185. if (!string.IsNullOrEmpty(signItem.SignSourceDate) && signItem.SignSourceDate.Contains("\\/"))
  186. {
  187. string srouceData = signItem.SignSourceDate.Replace("\\/", "/");
  188. bool jsonCheck = AlipaySignature.RSACheckContent(srouceData, signItem.Sign, alipayPublicKey, charset);
  189. if (!jsonCheck)
  190. {
  191. throw new AopException(
  192. "sign check fail: check Sign and Data Fail JSON also");
  193. }
  194. }
  195. else
  196. {
  197. throw new AopException(
  198. "sign check fail: check Sign and Data Fail!");
  199. }
  200. }
  201. }
  202. }
  203. #endregion
  204. }
  205. }