Ei kuvausta
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

APIClient.cs 20KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547
  1. using System;
  2. using System.IO;
  3. using System.Linq;
  4. using System.Net.Http;
  5. using System.Net.Http.Headers;
  6. using System.Text;
  7. //using System.Text.Json;
  8. using System.Threading.Tasks;
  9. using System.Web;
  10. using System.Windows.Forms;
  11. using Newtonsoft.Json;
  12. using System.Net;
  13. namespace LrGetToken
  14. {
  15. public class APIClient
  16. {
  17. /// <summary>
  18. /// 请求服务器域名,默认https://api.kingdee.com/
  19. /// </summary>
  20. private string _baseUrl = "https://api.kingdee.com/";
  21. /// <summary>
  22. /// 客户Id
  23. /// </summary>
  24. private string _clientId = "";
  25. /// <summary>
  26. /// 客户秘钥
  27. /// </summary>
  28. private string _clientSecret = "";
  29. /// <summary>
  30. /// 超时时间(秒)
  31. /// </summary>
  32. public int Timeout { get { return 10; } set { value = 10; } }
  33. /// <summary>
  34. /// 构造一个API客户端对象
  35. /// </summary>
  36. /// <param name="clientId">客户Id</param>
  37. /// <param name="clientSecret">客户秘钥</param>
  38. /// /// <param name="baseUrl">请求域名</param>
  39. public APIClient(string clientId, string clientSecret, string baseUrl)
  40. {
  41. this._clientId = clientId;
  42. this._clientSecret = clientSecret;
  43. this._baseUrl = baseUrl;
  44. }
  45. /// <summary>
  46. /// 构造一个API客户端对象
  47. /// </summary>
  48. /// <param name="clientId">客户Id</param>
  49. /// <param name="clientSecret">客户秘钥</param>
  50. public APIClient(string clientId, string clientSecret)
  51. {
  52. this._clientId = clientId;
  53. this._clientSecret = clientSecret;
  54. }
  55. /// <summary>
  56. /// 发起请求
  57. /// </summary>
  58. /// <param name="request"></param>
  59. /// <returns></returns>
  60. public async Task<HttpResponseMessage> Execute(APIRequest request, string api_nonce, string timeStamp)
  61. {
  62. using (HttpClient _client = new HttpClient())
  63. {
  64. _client.Timeout = TimeSpan.FromSeconds((double)Timeout);
  65. BuildRequestHeader(_client.DefaultRequestHeaders, request, api_nonce, timeStamp);
  66. var uri = _baseUrl.TrimEnd('/') + "/" + request.Path + "?" + GetQueryString(request);
  67. if (request.Method == HttpMethod.Post)
  68. {
  69. if (string.IsNullOrEmpty(request.File))
  70. {
  71. var json = request.Body == null ? string.Empty : JsonConvert.SerializeObject(request.Body);
  72. return await _client.PostAsync(uri, new StringContent(json, Encoding.UTF8, request.ContentType));
  73. }
  74. else
  75. {
  76. //文件上传
  77. string boundary = "----WebKitFormBoundary{DateTime.Now.Ticks:x}";
  78. MultipartFormDataContent content = new MultipartFormDataContent(boundary);
  79. if (!File.Exists(request.File))
  80. {
  81. throw new Exception("路径不存在:{request.File}");
  82. }
  83. using (FileStream fStream = File.Open(request.File, FileMode.Open, FileAccess.Read))
  84. {
  85. content.Add(new StreamContent(fStream, (int)fStream.Length), "file", Path.GetFileName(request.File));
  86. return await _client.PostAsync(uri, content);
  87. }
  88. }
  89. }
  90. else if (request.Method == HttpMethod.Get)
  91. {
  92. return await _client.GetAsync(uri);
  93. }
  94. else if (request.Method == HttpMethod.Put)
  95. {
  96. var json = request.Body == null ? string.Empty : JsonConvert.SerializeObject(request.Body);
  97. return await _client.PutAsync(uri, new StringContent(json, Encoding.UTF8, request.ContentType));
  98. }
  99. else if (request.Method == HttpMethod.Delete)
  100. {
  101. return await _client.DeleteAsync(uri);
  102. }
  103. else
  104. {
  105. throw new Exception("Method:{request.Method} 参数不支持!");
  106. }
  107. }
  108. }
  109. public string HttpPost(APIRequest request, string ClientID, string outerInstanceId, string api_nonce, string timeStamp)
  110. {
  111. try
  112. {
  113. var uri = _baseUrl.TrimEnd('/') + "/" + request.Path + "?outerInstanceId=" + outerInstanceId;
  114. HttpWebRequest request1 = (HttpWebRequest)WebRequest.Create(uri);
  115. request1.ContentType = "application/json";
  116. request1.Method = "POST";
  117. //request1.Headers.Add("Content-Type", "application/json");
  118. request1.Headers.Add("X-Api-ClientID", ClientID);
  119. request1.Headers.Add("X-Api-Auth-Version", "2.0");
  120. request1.Headers.Add("X-Api-TimeStamp", timeStamp.ToString());
  121. request1.Headers.Add("X-Api-SignHeaders", "X-Api-TimeStamp,X-Api-Nonce");
  122. request1.Headers.Add("X-Api-Nonce", api_nonce.ToString());
  123. request1.Headers.Add("X-Api-Signature", GetSignature(request, api_nonce.ToString(), timeStamp.ToString()));
  124. //string postData = "key1=value1&key2=value2";
  125. //GetHeader(request1, request);
  126. //Stream requestStream = request1.GetRequestStream();
  127. //StreamWriter streamWriter = new StreamWriter(requestStream);
  128. //streamWriter.Write(postDataStr);
  129. //streamWriter.Close();
  130. HttpWebResponse response = (HttpWebResponse)request1.GetResponse();
  131. Stream responseStream = response.GetResponseStream();
  132. StreamReader streamReader = new StreamReader(responseStream);
  133. string retString = streamReader.ReadToEnd();
  134. streamReader.Close();
  135. responseStream.Close();
  136. return retString;
  137. }
  138. catch (Exception ex)
  139. {
  140. Console.WriteLine(ex.Message);
  141. return "";
  142. }
  143. }
  144. public string HttpPost1(APIRequest request, string apptoken, string ClientID, string api_nonce, string timeStamp, string postbody)
  145. {
  146. try
  147. {
  148. var uri = _baseUrl.TrimEnd('/') + "/" + request.Path;
  149. HttpWebRequest request1 = (HttpWebRequest)WebRequest.Create(uri);
  150. request1.ContentType = "application/json";
  151. request1.Method = "POST";
  152. //request1.Headers.Add("Content-Type", "application/json");
  153. request1.Headers.Add("X-Api-ClientID", ClientID);
  154. request1.Headers.Add("X-Api-Auth-Version", "2.0");
  155. request1.Headers.Add("X-Api-TimeStamp", timeStamp.ToString());
  156. request1.Headers.Add("X-Api-SignHeaders", "X-Api-TimeStamp,X-Api-Nonce");
  157. request1.Headers.Add("X-Api-Nonce", api_nonce.ToString());
  158. request1.Headers.Add("X-Api-Signature", GetSignature(request, api_nonce.ToString(), timeStamp.ToString()));
  159. request1.Headers.Add("app-token", apptoken);
  160. request1.Headers.Add("X-GW-Router-Addr", "https://tf.jdy.com");
  161. //string postData = "key1=value1&key2=value2";
  162. //GetHeader(request1, request);
  163. //Stream requestStream = request1.GetRequestStream();
  164. //StreamWriter streamWriter = new StreamWriter(requestStream);
  165. //streamWriter.Write(postDataStr);
  166. //streamWriter.Close();
  167. // 写入请求体(body)
  168. using (Stream requestStream = request1.GetRequestStream())
  169. {
  170. using (StreamWriter streamWriter = new StreamWriter(requestStream))
  171. {
  172. streamWriter.Write(postbody); // postDataStr是你要发送的JSON数据
  173. }
  174. }
  175. // 获取响应
  176. HttpWebResponse response = (HttpWebResponse)request1.GetResponse();
  177. // 读取响应内容
  178. using (Stream responseStream = response.GetResponseStream())
  179. {
  180. using (StreamReader streamReader = new StreamReader(responseStream))
  181. {
  182. string retString = streamReader.ReadToEnd();
  183. return retString;
  184. }
  185. }
  186. // HttpWebResponse response = (HttpWebResponse)request1.GetResponse();
  187. // Stream responseStream = response.GetResponseStream();
  188. //StreamReader streamReader = new StreamReader(responseStream);
  189. // string retString = streamReader.ReadToEnd();
  190. // streamReader.Close();
  191. // responseStream.Close();
  192. //return retString;
  193. }
  194. catch (Exception ex)
  195. {
  196. Console.WriteLine(ex.Message);
  197. return "";
  198. }
  199. }
  200. // 定义一个委托,确保能够跨线程调用
  201. public delegate void UpdateResponseTextDelegate(string response);
  202. public string SaveBill(APIRequest request, string ClientID, string appToken, string api_nonce, string timeStamp,string billContent)
  203. {
  204. try
  205. {
  206. var uri = _baseUrl.TrimEnd('/') + "/" + request.Path;
  207. HttpWebRequest request1 = (HttpWebRequest)WebRequest.Create(uri);
  208. request1.ContentType = "application/json";
  209. request1.Method = "POST";
  210. // GetHeader1(request1, request, api_nonce, timeStamp);
  211. //request1.Headers.Add("Content-Type", "application/json");
  212. request1.Headers.Add("X-Api-ClientID", ClientID);
  213. request1.Headers.Add("X-Api-Auth-Version", "2.0");
  214. request1.Headers.Add("X-Api-TimeStamp", timeStamp.ToString());
  215. request1.Headers.Add("X-Api-SignHeaders", "X-Api-TimeStamp,X-Api-Nonce");
  216. request1.Headers.Add("X-Api-Nonce", api_nonce.ToString());
  217. request1.Headers.Add("X-Api-Signature", GetSignature(request, api_nonce.ToString(), timeStamp.ToString()));
  218. request1.Headers.Add("app-token", appToken);
  219. //request1.Headers.Add("X-GW-Router-Addr", "https://tf.jdy.com");
  220. // string postData = "key1=value1&key2=value2";
  221. if (billContent != "")
  222. {
  223. byte[] byteArray = Encoding.UTF8.GetBytes(billContent);
  224. request1.ContentLength = byteArray.Length;
  225. Stream dataStream = request1.GetRequestStream();
  226. // Write the data to the request stream
  227. dataStream.Write(byteArray, 0, byteArray.Length);
  228. // Close the Stream object
  229. dataStream.Close();
  230. //Stream requestStream = request1.GetRequestStream();
  231. //StreamWriter streamWriter = new StreamWriter(requestStream);
  232. //streamWriter.Write(billContent);
  233. //streamWriter.Close();
  234. }
  235. //GetHeader(request1, request);
  236. //Stream requestStream = request1.GetRequestStream();
  237. //StreamWriter streamWriter = new StreamWriter(requestStream);
  238. //streamWriter.Write(postDataStr);
  239. //streamWriter.Close();
  240. HttpWebResponse response = (HttpWebResponse)request1.GetResponse();
  241. Stream responseStream = response.GetResponseStream();
  242. StreamReader streamReader = new StreamReader(responseStream);
  243. string retString = streamReader.ReadToEnd();
  244. streamReader.Close();
  245. responseStream.Close();
  246. return retString;
  247. }
  248. catch (Exception ex)
  249. {
  250. Console.WriteLine("Error Message: " + ex.Message);
  251. if (ex is WebException webEx)
  252. {
  253. if (webEx.Response != null)
  254. {
  255. using (var responseStream = webEx.Response.GetResponseStream())
  256. using (var reader = new StreamReader(responseStream))
  257. {
  258. string responseBody = reader.ReadToEnd();
  259. Console.WriteLine("Response Body: " + responseBody);
  260. }
  261. }
  262. }
  263. return "";
  264. }
  265. }
  266. public string HttpGet(APIRequest request, string api_nonce, string timeStamp)
  267. {
  268. try
  269. {
  270. var uri = _baseUrl.TrimEnd('/') + "/" + request.Path + "?" + GetQueryString(request);
  271. HttpWebRequest request1 = (HttpWebRequest)WebRequest.Create(uri);
  272. GetHeader(request1, request, api_nonce, timeStamp); //加入header
  273. HttpWebResponse response = (HttpWebResponse)request1.GetResponse();
  274. Stream myResponseStream = response.GetResponseStream();
  275. StreamReader streamReader = new StreamReader(myResponseStream);
  276. string retString = streamReader.ReadToEnd();
  277. streamReader.Close();
  278. myResponseStream.Close();
  279. return retString;
  280. }
  281. catch (Exception ex)
  282. {
  283. Console.WriteLine("Error Message: " + ex.Message);
  284. if (ex is WebException webEx)
  285. {
  286. if (webEx.Response != null)
  287. {
  288. using (var responseStream = webEx.Response.GetResponseStream())
  289. using (var reader = new StreamReader(responseStream))
  290. {
  291. string responseBody = reader.ReadToEnd();
  292. Console.WriteLine("Response Body: " + responseBody);
  293. }
  294. }
  295. }
  296. return "";
  297. }
  298. }
  299. public string HttpGet_pur_in(APIRequest request)
  300. {
  301. try
  302. {
  303. var uri = _baseUrl.TrimEnd('/') + "/" + request.Path + "?" + GetQueryString(request);
  304. HttpWebRequest request1 = (HttpWebRequest)WebRequest.Create(uri);
  305. // GetHeader(request1, request, api_nonce, timeStamp); //加入header
  306. HttpWebResponse response = (HttpWebResponse)request1.GetResponse();
  307. Stream myResponseStream = response.GetResponseStream();
  308. StreamReader streamReader = new StreamReader(myResponseStream);
  309. string retString = streamReader.ReadToEnd();
  310. streamReader.Close();
  311. myResponseStream.Close();
  312. return retString;
  313. }
  314. catch (Exception ex)
  315. {
  316. Console.WriteLine("Error Message: " + ex.Message);
  317. if (ex is WebException webEx)
  318. {
  319. if (webEx.Response != null)
  320. {
  321. using (var responseStream = webEx.Response.GetResponseStream())
  322. using (var reader = new StreamReader(responseStream))
  323. {
  324. string responseBody = reader.ReadToEnd();
  325. Console.WriteLine("Response Body: " + responseBody);
  326. }
  327. }
  328. }
  329. return "";
  330. }
  331. }
  332. private void GetHeader1(HttpWebRequest request1, APIRequest request, string api_nonce, string timeStamp)
  333. {
  334. //var api_nonce = new Random().Next(100000000, 999999999);
  335. //var timeStamp = (int)(DateTime.Now.ToLocalTime() - DateTime.Parse("1970-01-01").ToLocalTime()).TotalSeconds;
  336. request1.Headers.Add("X-Api-ClientID", _clientId);
  337. request1.Headers.Add("X-Api-Auth-Version", "2.0");
  338. request1.Headers.Add("X-Api-TimeStamp", timeStamp.ToString());
  339. request1.Headers.Add("X-Api-SignHeaders", "X-Api-Nonce,X-Api-TimeStamp");
  340. request1.Headers.Add("X-Api-Nonce", api_nonce.ToString());
  341. request1.Headers.Add("X-Api-Signature", GetSignature(request, api_nonce.ToString(), timeStamp.ToString()));
  342. //headers.Add("X-GW-Router-Addr", "https://tf.jdy.com/");
  343. if (request.Header.Any())
  344. {
  345. foreach (var hk in request.Header.Keys)
  346. {
  347. request1.Headers.Add(hk, request.Header[hk]);
  348. }
  349. }
  350. }
  351. private void GetHeader(HttpWebRequest request1, APIRequest request, string api_nonce, string timeStamp)
  352. {
  353. //var api_nonce = new Random().Next(100000000, 999999999);
  354. //var timeStamp = (int)(DateTime.Now.ToLocalTime() - DateTime.Parse("1970-01-01").ToLocalTime()).TotalSeconds;
  355. request1.Headers.Add("X-Api-ClientID", _clientId);
  356. request1.Headers.Add("X-Api-Auth-Version", "2.0");
  357. request1.Headers.Add("X-Api-TimeStamp", timeStamp.ToString());
  358. request1.Headers.Add("X-Api-SignHeaders", "X-Api-Nonce,X-Api-TimeStamp");
  359. request1.Headers.Add("X-Api-Nonce", api_nonce.ToString());
  360. request1.Headers.Add("X-Api-Signature", GetSignature(request, api_nonce.ToString(), timeStamp.ToString()));
  361. //headers.Add("X-GW-Router-Addr", "https://tf.jdy.com/");
  362. if (request.Header.Any())
  363. {
  364. foreach (var hk in request.Header.Keys)
  365. {
  366. request1.Headers.Add(hk, request.Header[hk]);
  367. }
  368. }
  369. }
  370. public void BuildRequestHeader(HttpRequestHeaders headers, APIRequest request, string api_nonce, string timeStamp)
  371. {
  372. //var api_nonce = new Random().Next(100000000, 999999999);
  373. //var timeStamp = (int)(DateTime.Now.ToLocalTime() - DateTime.Parse("1970-01-01").ToLocalTime()).TotalSeconds;
  374. headers.Add("X-Api-Nonce", api_nonce.ToString());
  375. headers.Add("X-Api-Auth-Version", "2.0");
  376. headers.Add("X-Api-TimeStamp", timeStamp.ToString());
  377. headers.Add("X-Api-ClientID", _clientId);
  378. headers.Add("X-Api-Signature", GetSignature(request, api_nonce.ToString(), timeStamp.ToString()));
  379. headers.Add("X-Api-SignHeaders", "X-Api-Nonce,X-Api-TimeStamp");
  380. headers.Add("X-GW-Router-Addr", "https://tf.jdy.com/");
  381. if (request.Header.Any())
  382. {
  383. foreach (var hk in request.Header.Keys)
  384. {
  385. headers.Add(hk, request.Header[hk]);
  386. }
  387. }
  388. }
  389. public string GetSignature(APIRequest request, string nonce, string timestamp)
  390. {
  391. var querySign = GetQueryString(request, true);
  392. var my_sign = "";
  393. StringBuilder sb = new StringBuilder();
  394. sb.Append(request.Method.ToString().ToUpper());
  395. sb.Append('\n');
  396. sb.Append(PathEncode(request.Path));
  397. sb.Append('\n');
  398. sb.Append(querySign);
  399. sb.Append('\n');
  400. sb.Append("x-api-nonce:" + nonce);
  401. sb.Append('\n');
  402. sb.Append("x-api-timestamp:" + timestamp);
  403. sb.Append('\n');
  404. my_sign = SHAHelper.HmacSHA256(_clientSecret, sb.ToString());
  405. return SHAHelper.HmacSHA256(_clientSecret, sb.ToString());
  406. }
  407. private string PostGetSignature(APIRequest request, string nonce, string timestamp)
  408. {
  409. var querySign = PostGetQueryString(request, true);
  410. StringBuilder sb = new StringBuilder();
  411. sb.Append(request.Method.ToString().ToUpper());
  412. sb.Append('\n');
  413. sb.Append(PathEncode(request.Path));
  414. sb.Append('\n');
  415. sb.Append(querySign);
  416. sb.Append('\n');
  417. sb.Append("x-api-nonce:" + nonce);
  418. sb.Append('\n');
  419. sb.Append("x-api-timestamp:" + timestamp);
  420. sb.Append('\n');
  421. return SHAHelper.HmacSHA256(_clientSecret, sb.ToString());
  422. }
  423. /// <summary>
  424. /// Url Path部分Url编码
  425. /// </summary>
  426. /// <param name="path"></param>
  427. /// <returns></returns>
  428. private static string PathEncode(string path)
  429. {
  430. path = HttpUtility.UrlEncode("/" + path.TrimStart('/')).Replace("%2f", "%2F").Replace("%2d", "%2D").Replace("(", "%28").Replace(")", "%29");
  431. return path;
  432. }
  433. /// <summary>
  434. /// 查询字符串部分拼接
  435. /// </summary>
  436. /// <param name="request"></param>
  437. /// <returns></returns>
  438. private static string GetQueryString(APIRequest request, bool doubleEncode = false)
  439. {
  440. var querySign = string.Empty;
  441. if (request.Params != null && request.Params.Keys != null)
  442. {
  443. foreach (var key in request.Params.Keys)
  444. {
  445. if (doubleEncode)
  446. {
  447. querySign = querySign
  448. + "&" + key.ToString() + "="
  449. + HttpUtility.UrlEncode(HttpUtility.UrlEncode(request.Params[key])).Replace("+", "%20");//.ToUpper();
  450. }
  451. else
  452. {
  453. querySign = querySign
  454. + "&" + key.ToString() + "="
  455. + HttpUtility.UrlEncode(request.Params[key]).Replace("+", "%20");//.ToUpper();
  456. }
  457. }
  458. querySign = querySign.TrimStart('&');
  459. }
  460. return querySign;
  461. }
  462. private static string PostGetQueryString(APIRequest request, bool doubleEncode = false)
  463. {
  464. var querySign = string.Empty;
  465. if (request.Params != null && request.Params.Keys != null)
  466. {
  467. foreach (var key in request.Params.Keys)
  468. {
  469. if (doubleEncode)
  470. {
  471. querySign = querySign
  472. + "&" + key.ToString() + "="
  473. + HttpUtility.UrlEncode(HttpUtility.UrlEncode(request.Params[key])).Replace("+", "%20").ToUpper();
  474. }
  475. else
  476. {
  477. querySign = querySign
  478. + "&" + key.ToString() + "="
  479. + HttpUtility.UrlEncode(request.Params[key]).Replace("+", "%20").ToUpper();
  480. }
  481. }
  482. querySign = querySign.TrimStart('&');
  483. }
  484. return querySign;
  485. }
  486. }
  487. }