ApiHelper.cs 40 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Collections.Specialized;
  4. using System.Diagnostics;
  5. using System.IO;
  6. using System.Linq;
  7. using System.Net;
  8. using System.Net.Http;
  9. using System.Text;
  10. using System.Text.Encodings.Web;
  11. using System.Threading.Tasks;
  12. using System.Web;
  13. using WS;
  14. using WS.Http;
  15. using WS.IO;
  16. using WS.IO.Zip;
  17. namespace QM.KJGH.CGGL.NMCGHJ
  18. {
  19. public class ApiHelper
  20. {
  21. /// <summary>
  22. /// 格式化URL参数
  23. /// </summary>
  24. /// <param name="param">参数</param>
  25. /// <param name="url">url</param>
  26. public static string FormatUrlParam(Dictionary<string, string> param, string url = null)
  27. {
  28. var strPar = param.Keys.Select(k => { return $"{k}={param[k]}"; }).Join("&");
  29. if (!string.IsNullOrWhiteSpace(url))
  30. {
  31. strPar = url + (url.IndexOf("?") >= 0 ? "&" : "?") + strPar;
  32. }
  33. return strPar;
  34. }
  35. /// <summary>
  36. /// 获取response header中Content-Disposition中的filename值
  37. /// </summary>
  38. /// <param name="response"></param>
  39. /// <returns></returns>
  40. private static string GetFileName(HttpWebResponse response)
  41. {
  42. var contentHeader = response.Headers["Content-Disposition"];
  43. string filename = null;
  44. if (contentHeader != null)
  45. {
  46. filename = contentHeader.Split("filename=")[1].Trim();
  47. if (filename.Contains("filename*=UTF-8''"))
  48. {
  49. filename = filename.Split("filename*=UTF-8''")[1].Trim();
  50. }
  51. WS.Log.RunLog.Debug("HESD:" + filename);
  52. WS.Log.RunLog.Debug("HESD:" + HttpUtility.UrlDecode(filename));
  53. filename = HttpUtility.UrlDecode(filename);
  54. }
  55. return filename;
  56. }
  57. /// <summary>
  58. /// multipart/form-data上传文件
  59. /// </summary>
  60. /// <param name="url">请求的url地址</param>
  61. /// <param name="postDict">post参数</param>
  62. /// <param name="fileName">文件名</param>
  63. /// <param name="file">文件</param>
  64. /// <param name="fileKeyName">文件这一项参数的key</param>
  65. /// <param name="timeOut">超时间隔_秒</param>
  66. /// <returns>失败返回null</returns>
  67. public static string HttpPostData(string url, Dictionary<string,string> postDict,
  68. string fileName, string filePath, string token, string fileKeyName = "file", int timeOut = 120)
  69. {
  70. System.GC.Collect();//垃圾回收,回收没有正常关闭的http连接
  71. timeOut = timeOut * 1000;
  72. string responseContent;
  73. MemoryStream memStream = null;
  74. Stream requestStream = null;
  75. HttpWebResponse httpWebResponse = null;
  76. HttpWebRequest webRequest = null;
  77. try
  78. {
  79. memStream = new MemoryStream();
  80. webRequest = (HttpWebRequest)WebRequest.Create(url);
  81. // 边界符
  82. var boundary = "---------------" + DateTime.Now.Ticks.ToString("x");
  83. // 边界符
  84. var beginBoundary = Encoding.UTF8.GetBytes("--" + boundary + "\r\n");
  85. // 最后的结束符
  86. var endBoundary = Encoding.UTF8.GetBytes("--" + boundary + "--\r\n");
  87. // 设置属性
  88. webRequest.Method = "POST";
  89. webRequest.Timeout = timeOut;
  90. webRequest.ContentType = "multipart/form-data; boundary=" + boundary;
  91. webRequest.Headers.Add("Authorization", token);
  92. // 写入字符串的Key
  93. var stringKeyHeader = "--" + boundary +
  94. "\r\nContent-Disposition: form-data; name=\"{0}\"" +
  95. "\r\n\r\n{1}\r\n";
  96. if(postDict != null)
  97. foreach (byte[] formitembytes in from string key in postDict.Keys
  98. select string.Format(stringKeyHeader, key, postDict[key])
  99. into formitem
  100. select Encoding.UTF8.GetBytes(formitem))
  101. {
  102. memStream.Write(formitembytes, 0, formitembytes.Length);
  103. }
  104. // 写入文件
  105. const string filePartHeader =
  106. "Content-Disposition: form-data; name=\"{0}\"; filename=\"{1}\"\r\n" +
  107. "Content-Type: application/octet-stream\r\n\r\n";
  108. var header = string.Format(filePartHeader, fileKeyName, fileName);
  109. var headerbytes = Encoding.UTF8.GetBytes(header);
  110. memStream.Write(beginBoundary, 0, beginBoundary.Length);
  111. memStream.Write(headerbytes, 0, headerbytes.Length);
  112. var buffer = new byte[1024];
  113. int bytesRead; // =0
  114. var file = new FileStream(filePath, FileMode.Open, FileAccess.Read);
  115. file.Seek(0, SeekOrigin.Begin);
  116. while ((bytesRead = file.Read(buffer, 0, buffer.Length)) != 0)
  117. {
  118. memStream.Write(buffer, 0, bytesRead);
  119. }
  120. file.Close();
  121. file.Dispose();
  122. // 写入换行
  123. var contentLine = Encoding.ASCII.GetBytes("\r\n");
  124. memStream.Write(contentLine, 0, contentLine.Length);
  125. // 写入最后的结束边界符
  126. memStream.Write(endBoundary, 0, endBoundary.Length);
  127. webRequest.ContentLength = memStream.Length;
  128. requestStream = webRequest.GetRequestStream();
  129. memStream.Position = 0;
  130. var tempBuffer = new byte[memStream.Length];
  131. memStream.Read(tempBuffer, 0, tempBuffer.Length);
  132. //memStream.Close();
  133. requestStream.Write(tempBuffer, 0, tempBuffer.Length);
  134. //requestStream.Close();
  135. try
  136. {
  137. httpWebResponse = (HttpWebResponse)webRequest.GetResponse();
  138. }
  139. catch (WebException ex)
  140. {
  141. httpWebResponse = (HttpWebResponse)ex.Response;
  142. }
  143. using (var httpStreamReader = new StreamReader(httpWebResponse.GetResponseStream(),
  144. Encoding.GetEncoding("utf-8")))
  145. {
  146. responseContent = httpStreamReader.ReadToEnd();
  147. }
  148. }
  149. finally
  150. {
  151. if (memStream != null) { memStream.Close(); }
  152. if (requestStream != null) { requestStream.Close(); }
  153. if (httpWebResponse != null) { httpWebResponse.Close(); }
  154. if (webRequest != null) { webRequest.Abort(); }
  155. }
  156. return responseContent;
  157. }
  158. /// <summary>
  159. /// multipart/form-data上传文件(多header)
  160. /// </summary>
  161. /// <param name="url">请求的url地址</param>
  162. /// <param name="postDict">post参数</param>
  163. /// <param name="fileName">文件名</param>
  164. /// <param name="file">文件</param>
  165. /// <param name="fileKeyName">文件这一项参数的key</param>
  166. /// <param name="timeOut">超时间隔_秒</param>
  167. /// <returns>失败返回null</returns>
  168. public static string HttpPostDataNm2(string url, Dictionary<string, string> postDict,
  169. string fileName, string filePath, Dictionary<string, string> headers, string fileKeyName = "file", int timeOut = 120)
  170. {
  171. WS.Log.RunLog.Debug($"HttpPostDataNm2:{url} = {postDict.ToJson()} = {fileName} = {filePath} = {headers.ToJson()} = {fileKeyName} = {timeOut}");
  172. System.GC.Collect();//垃圾回收,回收没有正常关闭的http连接
  173. timeOut = timeOut * 1000;
  174. string responseContent;
  175. MemoryStream memStream = null;
  176. Stream requestStream = null;
  177. HttpWebResponse httpWebResponse = null;
  178. HttpWebRequest webRequest = null;
  179. ServicePointManager.DefaultConnectionLimit = 1000;
  180. try
  181. {
  182. memStream = new MemoryStream();
  183. webRequest = (HttpWebRequest)WebRequest.Create(url);
  184. // 边界符
  185. var boundary = "---------------" + DateTime.Now.Ticks.ToString("x");
  186. // 边界符
  187. var beginBoundary = Encoding.UTF8.GetBytes("--" + boundary + "\r\n");
  188. // 最后的结束符
  189. var endBoundary = Encoding.UTF8.GetBytes("--" + boundary + "--\r\n");
  190. // 设置属性
  191. webRequest.Method = "POST";
  192. webRequest.Timeout = timeOut;
  193. webRequest.ReadWriteTimeout = timeOut;
  194. webRequest.ContentType = "multipart/form-data; boundary=" + boundary;
  195. webRequest.KeepAlive = false;
  196. if (headers != null)
  197. {
  198. foreach (var key in headers.Keys)
  199. {
  200. webRequest.Headers.Add(key, headers[key]);
  201. }
  202. }
  203. // 写入字符串的Key
  204. var stringKeyHeader = "--" + boundary +
  205. "\r\nContent-Disposition: form-data; name=\"{0}\"" +
  206. "\r\n\r\n{1}\r\n";
  207. if (postDict != null)
  208. foreach (byte[] formitembytes in from string key in postDict.Keys
  209. select string.Format(stringKeyHeader, key, postDict[key])
  210. into formitem
  211. select Encoding.UTF8.GetBytes(formitem))
  212. {
  213. memStream.Write(formitembytes, 0, formitembytes.Length);
  214. }
  215. // 写入文件
  216. const string filePartHeader =
  217. "Content-Disposition: form-data; name=\"{0}\"; filename=\"{1}\"\r\n" +
  218. "Content-Type: application/octet-stream\r\n\r\n";
  219. var header = string.Format(filePartHeader, fileKeyName, fileName);
  220. var headerbytes = Encoding.UTF8.GetBytes(header);
  221. memStream.Write(beginBoundary, 0, beginBoundary.Length);
  222. memStream.Write(headerbytes, 0, headerbytes.Length);
  223. var buffer = new byte[1024];
  224. int bytesRead; // =0
  225. var file = new FileStream(filePath, FileMode.Open, FileAccess.Read);
  226. WS.Log.RunLog.Debug($"文件是空的吗:{file == null}");
  227. file.Seek(0, SeekOrigin.Begin);
  228. while ((bytesRead = file.Read(buffer, 0, buffer.Length)) != 0)
  229. {
  230. memStream.Write(buffer, 0, bytesRead);
  231. }
  232. file.Close();
  233. file.Dispose();
  234. // 写入换行
  235. var contentLine = Encoding.ASCII.GetBytes("\r\n");
  236. memStream.Write(contentLine, 0, contentLine.Length);
  237. // 写入最后的结束边界符
  238. memStream.Write(endBoundary, 0, endBoundary.Length);
  239. webRequest.ContentLength = memStream.Length;
  240. requestStream = webRequest.GetRequestStream();
  241. memStream.Position = 0;
  242. var tempBuffer = new byte[memStream.Length];
  243. memStream.Read(tempBuffer, 0, tempBuffer.Length);
  244. //memStream.Close();
  245. requestStream.Write(tempBuffer, 0, tempBuffer.Length);
  246. //requestStream.Close();
  247. WS.Log.RunLog.Debug($"222222222222");
  248. var ermsg = string.Empty;
  249. try
  250. {
  251. #region 鄂尔多斯
  252. //TODO 鄂尔多斯上传有时候等不到回复,网上查加这个,试试
  253. //http://t.zoukankan.com/lansehai-p-5938440.html
  254. //webRequest.ServicePoint.Expect100Continue = false;
  255. //ServicePointManager.Expect100Continue = false;
  256. #endregion
  257. httpWebResponse = (HttpWebResponse)webRequest.GetResponse();
  258. }
  259. catch (WebException ex)
  260. {
  261. WS.Log.RunLog.Error( ex, $"HttpWebResponse异常");
  262. httpWebResponse = (HttpWebResponse)ex.Response;
  263. }
  264. WS.Log.RunLog.Debug($"HttpWebResponse是空吗? {httpWebResponse == null}");
  265. if(httpWebResponse != null)
  266. {
  267. WS.Log.RunLog.Debug($"Response => {httpWebResponse.ToJson()}");
  268. }
  269. using (var httpStreamReader = new StreamReader(httpWebResponse.GetResponseStream(),
  270. Encoding.GetEncoding("utf-8")))
  271. {
  272. WS.Log.RunLog.Debug($"HttpStreamReader是空吗? {httpStreamReader == null}");
  273. responseContent = httpStreamReader.ReadToEnd();
  274. }
  275. }
  276. finally
  277. {
  278. try
  279. {
  280. if (memStream != null) { memStream.Close(); memStream.Dispose(); memStream = null; }
  281. }
  282. catch (Exception ex)
  283. {
  284. WS.Log.RunLog.Error(ex, $"关闭 MemoryStream");
  285. }
  286. try
  287. {
  288. if (requestStream != null) { requestStream.Close(); requestStream.Dispose(); requestStream = null; }
  289. }
  290. catch (Exception ex)
  291. {
  292. WS.Log.RunLog.Error(ex, $"关闭 RequestStream");
  293. }
  294. try
  295. {
  296. if (httpWebResponse != null) { httpWebResponse.Close(); httpWebResponse.Dispose(); httpWebResponse = null; }
  297. }
  298. catch (Exception ex)
  299. {
  300. WS.Log.RunLog.Error(ex, $"关闭 HttpWebResponse");
  301. }
  302. try
  303. {
  304. if (webRequest != null) { webRequest.Abort(); webRequest = null; }
  305. }
  306. catch (Exception ex)
  307. {
  308. WS.Log.RunLog.Error(ex, $"关闭 HttpWebRequest");
  309. }
  310. System.GC.Collect();//垃圾回收,回收没有正常关闭的http连接
  311. }
  312. return responseContent;
  313. }
  314. /// <summary>
  315. /// 使用HttpClient上传
  316. /// </summary>
  317. /// <param name="url">请求的url地址</param>
  318. /// <param name="postDict">post参数</param>
  319. /// <param name="fileName">文件名</param>
  320. /// <param name="file">文件</param>
  321. /// <param name="fileKeyName">文件这一项参数的key</param>
  322. /// <param name="timeOut">超时间隔_秒</param>
  323. /// <returns></returns>
  324. public static string HttpClientPost(string url, Dictionary<string, string> postDict,
  325. string fileName, string filePath, Dictionary<string, string> headers, string fileKeyName = "file", int timeOut = 120)
  326. {
  327. //执行代码
  328. using (HttpClient client = new HttpClient())
  329. {
  330. var content = new MultipartFormDataContent();
  331. //头
  332. if (headers != null)
  333. {
  334. foreach (var key in headers.Keys)
  335. {
  336. client.DefaultRequestHeaders.Add(key, headers[key]);
  337. }
  338. }
  339. //添加字符串参数
  340. if (postDict != null)
  341. {
  342. foreach (var key in postDict.Keys)
  343. {
  344. if (postDict[key] != null)
  345. content.Add(new StringContent(postDict[key]), key);
  346. }
  347. }
  348. client.Timeout = TimeSpan.FromSeconds(timeOut);
  349. //添加文件参数,参数名为files,文件名为123.png
  350. content.Add(new ByteArrayContent(System.IO.File.ReadAllBytes(filePath)), fileKeyName, fileName);
  351. WS.Log.RunLog.Debug($"开始上传");
  352. var result = "";
  353. var task = Task.Factory.StartNew(() =>
  354. {
  355. result = client.PostAsync(url, content).Result.Content.ReadAsStringAsync().Result;
  356. WS.Log.RunLog.Debug($"新文件上传返回:" + result);
  357. });
  358. if (!task.Wait(TimeSpan.FromSeconds(timeOut)))
  359. {
  360. WS.Log.RunLog.Debug($"文件上传无返回超时");
  361. result = "{\"code\":999,\"success\":true,\"data\":{},\"msg\":\"文件上传无返回超时[{"+ timeOut + "}]!\"}";
  362. try
  363. {
  364. client.Dispose();
  365. }
  366. catch (Exception ex )
  367. {
  368. WS.Log.RunLog.Debug($"手动释放。。。"+ex.Message);
  369. }
  370. }
  371. return result;
  372. }
  373. }
  374. /// <summary>
  375. /// 上传文件,分片好用
  376. /// multipart/form-data上传文件
  377. /// </summary>
  378. /// <param name="url">请求的url地址</param>
  379. /// <param name="files">上传文件<name,文件路径></param>
  380. /// <param name="postData">post参数<key,value></param>
  381. /// <param name="urlParam">url参数<key,value></param>
  382. /// <param name="timeOut">超时间隔_秒</param>
  383. /// <returns>失败返回null</returns>
  384. public static string HttpPostFormdata(
  385. string url,
  386. Dictionary<string, string> urlParam = null,
  387. Dictionary<string, string> postData = null,
  388. Dictionary<string, string> files = null,
  389. Dictionary<string, string> headers = null,
  390. int timeOut = 120)
  391. {
  392. GC.Collect();//垃圾回收,回收没有正常关闭的http连接
  393. timeOut = timeOut * 1000;
  394. string responseContent;
  395. MemoryStream memStream = null;
  396. Stream requestStream = null;
  397. HttpWebResponse httpWebResponse = null;
  398. HttpWebRequest webRequest = null;
  399. try
  400. {
  401. memStream = new MemoryStream();
  402. #region URL参数
  403. if (urlParam != null && urlParam.Count > 0)
  404. {
  405. url = FormatUrlParam(urlParam, url);
  406. }
  407. #endregion
  408. // 边界符
  409. var boundary = $"---------------{DateTime.Now.Ticks.ToString("x")}";
  410. // 边界符
  411. var beginBoundary = Encoding.UTF8.GetBytes($"--{boundary}\r\n");
  412. // 最后的结束符
  413. var endBoundary = Encoding.UTF8.GetBytes($"--{boundary}--\r\n");
  414. // 设置属性
  415. webRequest = (HttpWebRequest)WebRequest.Create(url);
  416. webRequest.Method = "POST";
  417. webRequest.Timeout = timeOut;
  418. webRequest.ContentType = $"multipart/form-data; boundary={boundary}";
  419. #region Headers
  420. if (headers != null && headers.Count > 0)
  421. {
  422. foreach (var key in headers.Keys)
  423. {
  424. webRequest.Headers.Add(key, headers[key]);
  425. }
  426. }
  427. #endregion
  428. #region body参数
  429. var stringKeyHeader = $"--{boundary}" + "\r\nContent-Disposition: form-data; name=\"{0}\"\r\n\r\n{1}\r\n";
  430. if (postData != null && postData.Count > 0)
  431. foreach (byte[] formitembytes in from string key in postData.Keys
  432. select string.Format(stringKeyHeader, key, postData[key])
  433. into formitem
  434. select Encoding.UTF8.GetBytes(formitem))
  435. {
  436. memStream.Write(formitembytes, 0, formitembytes.Length);
  437. }
  438. #endregion
  439. #region 文件
  440. if (files != null && files.Count > 0)
  441. {
  442. foreach (var key in files.Keys)
  443. {
  444. const string filePartHeader = "Content-Disposition: form-data; name=\"{0}\"; filename=\"{1}\"\r\n"
  445. + "Content-Type: application/octet-stream\r\n\r\n";
  446. var header = string.Format(filePartHeader, key, Path.GetFileName(files[key]));
  447. var headerbytes = Encoding.UTF8.GetBytes(header);
  448. memStream.Write(beginBoundary, 0, beginBoundary.Length);
  449. memStream.Write(headerbytes, 0, headerbytes.Length);
  450. var buffer = new byte[1024];
  451. int bytesRead; // =0
  452. var file = new FileStream(files[key], FileMode.Open, FileAccess.Read);
  453. file.Seek(0, SeekOrigin.Begin);
  454. while ((bytesRead = file.Read(buffer, 0, buffer.Length)) != 0)
  455. {
  456. memStream.Write(buffer, 0, bytesRead);
  457. }
  458. file.Close();
  459. file.Dispose();
  460. // 写入换行
  461. var contentLine = Encoding.ASCII.GetBytes("\r\n");
  462. memStream.Write(contentLine, 0, contentLine.Length);
  463. }
  464. }
  465. #endregion
  466. // 写入最后的结束边界符
  467. memStream.Write(endBoundary, 0, endBoundary.Length);
  468. webRequest.ContentLength = memStream.Length;
  469. requestStream = webRequest.GetRequestStream();
  470. memStream.Position = 0;
  471. var tempBuffer = new byte[memStream.Length];
  472. memStream.Read(tempBuffer, 0, tempBuffer.Length);
  473. requestStream.Write(tempBuffer, 0, tempBuffer.Length);
  474. try
  475. {
  476. httpWebResponse = (HttpWebResponse)webRequest.GetResponse();
  477. }
  478. catch (WebException ex)
  479. {
  480. httpWebResponse = (HttpWebResponse)ex.Response;
  481. }
  482. using (var httpStreamReader = new StreamReader(httpWebResponse.GetResponseStream(), Encoding.GetEncoding("utf-8")))
  483. {
  484. responseContent = httpStreamReader.ReadToEnd();
  485. }
  486. }
  487. finally
  488. {
  489. if (memStream != null) { memStream.Close(); }
  490. if (requestStream != null) { requestStream.Close(); }
  491. if (httpWebResponse != null) { httpWebResponse.Close(); }
  492. if (webRequest != null) { webRequest.Abort(); }
  493. }
  494. return responseContent;
  495. }
  496. /// <summary>
  497. /// 上传文件,分片好用
  498. /// multipart/form-data上传文件
  499. /// </summary>
  500. /// <param name="url">请求的url地址</param>
  501. /// <param name="files">上传文件<name,文件路径></param>
  502. /// <param name="postData">post参数<key,value></param>
  503. /// <param name="urlParam">url参数<key,value></param>
  504. /// <param name="timeOut">超时间隔_秒</param>
  505. /// <returns>失败返回null</returns>
  506. public static string HttpGetFormdata(
  507. string url,
  508. Dictionary<string, string> urlParam = null,
  509. Dictionary<string, string> postData = null,
  510. Dictionary<string, string> files = null,
  511. Dictionary<string, string> headers = null,
  512. int timeOut = 120)
  513. {
  514. GC.Collect();//垃圾回收,回收没有正常关闭的http连接
  515. timeOut = timeOut * 1000;
  516. string responseContent;
  517. MemoryStream memStream = null;
  518. Stream requestStream = null;
  519. HttpWebResponse httpWebResponse = null;
  520. HttpWebRequest webRequest = null;
  521. try
  522. {
  523. memStream = new MemoryStream();
  524. #region URL参数
  525. if (urlParam != null && urlParam.Count > 0)
  526. {
  527. url = FormatUrlParam(urlParam, url);
  528. }
  529. #endregion
  530. // 边界符
  531. var boundary = $"---------------{DateTime.Now.Ticks.ToString("x")}";
  532. // 边界符
  533. var beginBoundary = Encoding.UTF8.GetBytes($"--{boundary}\r\n");
  534. // 最后的结束符
  535. var endBoundary = Encoding.UTF8.GetBytes($"--{boundary}--\r\n");
  536. // 设置属性
  537. webRequest = (HttpWebRequest)WebRequest.Create(url);
  538. webRequest.Method = "GET";
  539. webRequest.Timeout = timeOut;
  540. webRequest.ContentType = $"multipart/form-data; boundary={boundary}";
  541. #region Headers
  542. if (headers != null && headers.Count > 0)
  543. {
  544. foreach (var key in headers.Keys)
  545. {
  546. webRequest.Headers.Add(key, headers[key]);
  547. }
  548. }
  549. #endregion
  550. #region body参数
  551. var stringKeyHeader = $"--{boundary}" + "\r\nContent-Disposition: form-data; name=\"{0}\"\r\n\r\n{1}\r\n";
  552. if (postData != null && postData.Count > 0)
  553. foreach (byte[] formitembytes in from string key in postData.Keys
  554. select string.Format(stringKeyHeader, key, postData[key])
  555. into formitem
  556. select Encoding.UTF8.GetBytes(formitem))
  557. {
  558. memStream.Write(formitembytes, 0, formitembytes.Length);
  559. }
  560. #endregion
  561. #region 文件
  562. if (files != null && files.Count > 0)
  563. {
  564. foreach (var key in files.Keys)
  565. {
  566. const string filePartHeader = "Content-Disposition: form-data; name=\"{0}\"; filename=\"{1}\"\r\n"
  567. + "Content-Type: application/octet-stream\r\n\r\n";
  568. var header = string.Format(filePartHeader, key, Path.GetFileName(files[key]));
  569. var headerbytes = Encoding.UTF8.GetBytes(header);
  570. memStream.Write(beginBoundary, 0, beginBoundary.Length);
  571. memStream.Write(headerbytes, 0, headerbytes.Length);
  572. var buffer = new byte[1024];
  573. int bytesRead; // =0
  574. var file = new FileStream(files[key], FileMode.Open, FileAccess.Read);
  575. file.Seek(0, SeekOrigin.Begin);
  576. while ((bytesRead = file.Read(buffer, 0, buffer.Length)) != 0)
  577. {
  578. memStream.Write(buffer, 0, bytesRead);
  579. }
  580. file.Close();
  581. file.Dispose();
  582. // 写入换行
  583. var contentLine = Encoding.ASCII.GetBytes("\r\n");
  584. memStream.Write(contentLine, 0, contentLine.Length);
  585. }
  586. }
  587. #endregion
  588. // 写入最后的结束边界符
  589. memStream.Write(endBoundary, 0, endBoundary.Length);
  590. webRequest.ContentLength = memStream.Length;
  591. requestStream = webRequest.GetRequestStream();
  592. memStream.Position = 0;
  593. var tempBuffer = new byte[memStream.Length];
  594. memStream.Read(tempBuffer, 0, tempBuffer.Length);
  595. requestStream.Write(tempBuffer, 0, tempBuffer.Length);
  596. try
  597. {
  598. httpWebResponse = (HttpWebResponse)webRequest.GetResponse();
  599. }
  600. catch (WebException ex)
  601. {
  602. httpWebResponse = (HttpWebResponse)ex.Response;
  603. }
  604. using (var httpStreamReader = new StreamReader(httpWebResponse.GetResponseStream(), Encoding.GetEncoding("utf-8")))
  605. {
  606. responseContent = httpStreamReader.ReadToEnd();
  607. }
  608. }
  609. finally
  610. {
  611. if (memStream != null) { memStream.Close(); }
  612. if (requestStream != null) { requestStream.Close(); }
  613. if (httpWebResponse != null) { httpWebResponse.Close(); }
  614. if (webRequest != null) { webRequest.Abort(); }
  615. }
  616. return responseContent;
  617. }
  618. /// <summary>
  619. /// 下载文件
  620. /// </summary>
  621. /// <param name="url"></param>
  622. /// <param name="savePath"></param>
  623. /// <param name="headers"></param>
  624. public static string HttpDownFile(string url, string savePath, Dictionary<string, string> headers = null, int timeOut = 120)
  625. {
  626. timeOut = timeOut * 1000;
  627. byte[] fileBytes;
  628. string file = string.Empty;
  629. HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
  630. request.Method = "GET";
  631. request.Timeout = timeOut;
  632. if (headers != null)
  633. {
  634. foreach (var key in headers.Keys)
  635. {
  636. request.Headers.Add(key, headers[key]);
  637. }
  638. }
  639. using (WebResponse webRes = request.GetResponse())
  640. {
  641. int length = (int)webRes.ContentLength;
  642. HttpWebResponse response = webRes as HttpWebResponse;
  643. file = Path.Combine(savePath, GetFileName(response));
  644. Stream stream = response.GetResponseStream();
  645. //读取到内存
  646. MemoryStream stmMemory = new MemoryStream();
  647. byte[] buffer = new byte[length];
  648. int i;
  649. //将字节逐个放入到Byte中
  650. while ((i = stream.Read(buffer, 0, buffer.Length)) > 0)
  651. {
  652. stmMemory.Write(buffer, 0, i);
  653. }
  654. fileBytes = stmMemory.ToArray();//文件流Byte
  655. FileStream fs = new FileStream(file, FileMode.OpenOrCreate);
  656. stmMemory.WriteTo(fs);
  657. stmMemory.Close();
  658. fs.Close();
  659. }
  660. return file;
  661. }
  662. /// <summary>
  663. /// 获取文件MD5值
  664. /// </summary>
  665. /// <param name="file">文件绝对路径</param>
  666. /// <returns>MD5值</returns>
  667. public static string GetMD5HashFromFile(string file)
  668. {
  669. try
  670. {
  671. FileStream fileStream = new FileStream(file, FileMode.Open, FileAccess.Read);
  672. System.Security.Cryptography.MD5 md5 = new System.Security.Cryptography.MD5CryptoServiceProvider();
  673. byte[] retVal = md5.ComputeHash(fileStream);
  674. fileStream.Close();
  675. StringBuilder sb = new StringBuilder();
  676. for (int i = 0; i < retVal.Length; i++)
  677. {
  678. sb.Append(retVal[i].ToString("x2"));
  679. }
  680. return sb.ToString();
  681. }
  682. catch (Exception ex)
  683. {
  684. throw new UseMassageException("获取文件MD5值error:" + ex.Message);
  685. }
  686. }
  687. /// <summary>
  688. /// 合并
  689. /// </summary>
  690. /// <param name="finalFile">最终的文件名</param>
  691. /// <param name="fpList">分包</param>
  692. /// <returns></returns>
  693. public static string FileMerge(string finalFile, Dictionary<int,string> fpList, bool delfp = false)
  694. {
  695. if (File.Exists(finalFile)) File.Delete(finalFile);
  696. var errorMsg = new List<string>();
  697. //验证文件逻辑
  698. var index = 0;
  699. var files = new List<string>();
  700. foreach (var chunk in fpList.Keys)
  701. {
  702. if (index == 0) index = chunk;
  703. else if (chunk != index)
  704. {
  705. throw new UseMassageException($"缺少分片文件({chunk}),调用【检查文件分片信息接口(/api/open/results/md5)】检查已上传分包");
  706. }
  707. fpList[chunk] = FileManage.Instance.ToFullPath(fpList[chunk], false);
  708. if (!File.Exists(fpList[chunk]))
  709. {
  710. errorMsg.Add(chunk.ToString());
  711. }
  712. index++;
  713. files.Add(fpList[chunk]);
  714. }
  715. if (errorMsg.Count > 0)
  716. {
  717. throw new UseMassageException($"未接收到分片{errorMsg.Join("、")}的文件,请重新上传");
  718. }
  719. //文件合包
  720. if (fpList.Count > 1)
  721. {
  722. using (var fs = new FileStream(finalFile, FileMode.Create))
  723. {
  724. foreach (var part in files)
  725. {
  726. var bytes = File.ReadAllBytes(part);
  727. fs.Write(bytes, 0, bytes.Length);
  728. bytes = null;
  729. }
  730. }
  731. }
  732. else
  733. {
  734. File.Copy(files[0], finalFile);
  735. }
  736. //检查成果文件
  737. if (File.Exists(finalFile))
  738. {
  739. if (delfp)
  740. {
  741. foreach (var part in files)
  742. {
  743. try
  744. {
  745. File.Delete(part);//删除分块
  746. }
  747. catch (Exception)
  748. { }
  749. }
  750. }
  751. }
  752. else
  753. {
  754. throw new UseMassageException($"合包失败,请联系管理员");
  755. }
  756. //解压
  757. return WinRAR.UnRarOrZip(finalFile);
  758. }
  759. /// <summary>
  760. /// 下载文件
  761. /// </summary>
  762. /// <param name="url"></param>
  763. /// <param name="savePath"></param>
  764. /// <param name="headers"></param>
  765. public static string HttpDownFilePost(string url, string savePath, Dictionary<string, string> headers = null, int timeOut = 120)
  766. {
  767. timeOut = timeOut * 1000;
  768. byte[] fileBytes;
  769. string file = string.Empty;
  770. HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
  771. request.Method = "POST";
  772. request.Timeout = timeOut;
  773. if (headers != null)
  774. {
  775. foreach (var key in headers.Keys)
  776. {
  777. request.Headers.Add(key, headers[key]);
  778. }
  779. }
  780. WS.Log.RunLog.Debug($"准备下载文件:" + url);
  781. using (WebResponse webRes = request.GetResponse())
  782. {
  783. try
  784. {
  785. WS.Log.RunLog.Debug($"下载返回:" + webRes.ToJson());
  786. int length = (int)webRes.ContentLength;
  787. WS.Log.RunLog.Debug($"下载文件大小:" + length);
  788. HttpWebResponse response = webRes as HttpWebResponse;
  789. file = Path.Combine(savePath, GetFileName(response));
  790. WS.Log.RunLog.Debug($"下载文件路径:" + file);
  791. Stream stream = response.GetResponseStream();
  792. //读取到内存
  793. MemoryStream stmMemory = new MemoryStream();
  794. byte[] buffer = new byte[length];
  795. int i;
  796. //将字节逐个放入到Byte中
  797. while ((i = stream.Read(buffer, 0, buffer.Length)) > 0)
  798. {
  799. stmMemory.Write(buffer, 0, i);
  800. }
  801. fileBytes = stmMemory.ToArray();//文件流Byte
  802. FileStream fs = new FileStream(file, FileMode.OpenOrCreate);
  803. stmMemory.WriteTo(fs);
  804. stmMemory.Close();
  805. fs.Close();
  806. }
  807. catch (Exception ex)
  808. {
  809. WS.Log.RunLog.Error(ex, $"下载文件异常:" + ex.Message);
  810. throw;
  811. }
  812. }
  813. return file;
  814. }
  815. /// <summary>
  816. /// 下载文件
  817. /// </summary>
  818. /// <param name="url"></param>
  819. /// <param name="savePath"></param>
  820. /// <param name="headers"></param>
  821. public static string HttpDownFileOrDataPost(string url, string savePath, Dictionary<string, string> headers = null, int timeOut = 120)
  822. {
  823. timeOut = timeOut * 1000;
  824. byte[] fileBytes;
  825. string file = string.Empty;
  826. HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
  827. request.Method = "POST";
  828. request.Timeout = timeOut;
  829. if (headers != null)
  830. {
  831. foreach (var key in headers.Keys)
  832. {
  833. request.Headers.Add(key, headers[key]);
  834. }
  835. }
  836. WS.Log.RunLog.Debug($"准备下载文件:" + url);
  837. using (WebResponse webRes = request.GetResponse())
  838. {
  839. try
  840. {
  841. WS.Log.RunLog.Debug($"下载返回:" + webRes.ToJson());
  842. int length = (int)webRes.ContentLength;
  843. WS.Log.RunLog.Debug($"下载文件大小:" + length);
  844. if (length < 0)
  845. {
  846. var res = HttpHelper.HttpPost(url, string.Empty, headers);
  847. return res;
  848. }
  849. else
  850. {
  851. HttpWebResponse response = webRes as HttpWebResponse;
  852. file = Path.Combine(savePath, GetFileName(response));
  853. WS.Log.RunLog.Debug($"下载文件路径:" + file);
  854. Stream stream = response.GetResponseStream();
  855. //读取到内存
  856. MemoryStream stmMemory = new MemoryStream();
  857. byte[] buffer = new byte[length];
  858. int i;
  859. //将字节逐个放入到Byte中
  860. while ((i = stream.Read(buffer, 0, buffer.Length)) > 0)
  861. {
  862. stmMemory.Write(buffer, 0, i);
  863. }
  864. fileBytes = stmMemory.ToArray();//文件流Byte
  865. FileStream fs = new FileStream(file, FileMode.OpenOrCreate);
  866. stmMemory.WriteTo(fs);
  867. stmMemory.Close();
  868. fs.Close();
  869. }
  870. }
  871. catch (Exception ex)
  872. {
  873. WS.Log.RunLog.Error(ex, $"下载文件异常:" + ex.Message);
  874. throw;
  875. }
  876. }
  877. return file;
  878. }
  879. }
  880. }