WXService.aspx.cs 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511
  1. using LYFZ.Weixin.SDK;
  2. using LYFZ.WXLibrary;
  3. using System;
  4. using System.Collections.Generic;
  5. using System.IO;
  6. using System.Linq;
  7. using System.Text;
  8. using System.Web;
  9. using System.Web.UI;
  10. using System.Web.UI.WebControls;
  11. using System.Xml;
  12. using System.Xml.Linq;
  13. namespace LYFZ.WeixinServers.WeiXinAPP
  14. {
  15. public partial class WXService : System.Web.UI.Page
  16. {
  17. /// <summary>
  18. /// 壳域名
  19. /// </summary>
  20. string requestUrl = "";
  21. /// <summary>
  22. /// 加密锁域名
  23. /// </summary>
  24. string JMGDomainName = "-2";
  25. protected void Page_Load(object sender, EventArgs e)
  26. {
  27. /* string signature = Request["signature"];
  28. string timestamp = Request["timestamp"];
  29. string nonce = Request["nonce"];
  30. //回复普通文本消息
  31. string replayMsg = ReplayPassiveMessageAPI.RepayText("ozy4qt1eDxSxzCr0aNT0mXCWfrDE", "gh_3c884a361561", "TESTCOMPONENT_MSG_TYPE_TEXT_callback");
  32. string encryptMsg = replayMsg;
  33. var msg_signature = Request.QueryString.Get("msg_signature");
  34. var wxBizMsgCrypt = new Tencent.WXBizMsgCrypt(OpenPlatformConfig.OpenToken, OpenPlatformConfig.OpenEncodingAESKey, OpenPlatformConfig.OpenAppID);
  35. var ret = wxBizMsgCrypt.EncryptMsg(replayMsg, timestamp, nonce, ref encryptMsg);
  36. if (ret != 0)//加密失败
  37. {
  38. //TODO:开发者加密失败的业务处理逻辑
  39. LYFZ.WXLibrary.CommonHandleClass.WriteLog(string.Format("加密失败,加密消息返回{0},响应体{1}", ret, encryptMsg), JMGDomainName, Global.LogsDongleDomainList);
  40. }
  41. */
  42. try
  43. {
  44. if (Request["appid"] != null)
  45. {
  46. //新版接口请求处理
  47. this.OpenPlatformRetqusetHandle();
  48. /*LYFZ.WXLibrary.CommonHandleClass.WriteLog("进入自定义一般处理文件工功能" , Global.LogsDongleDomainList);
  49. LYFZ.WeixinServers.WeiXinAPP.Api.WeiXinService wxService = new Api.WeiXinService();
  50. wxService.ProcessRequest(HttpContext.Current);*/
  51. }
  52. else
  53. {
  54. WriteContent("");
  55. LYFZ.WXLibrary.CommonHandleClass.WriteLog("非法请求Url:" + this.Request.Url, "-2", Global.LogsDongleDomainList);
  56. }
  57. }
  58. catch//(Exception ex)
  59. {
  60. WriteContent("");
  61. //LYFZ.WXLibrary.CommonHandleClass.WriteLog("Load处理出错:"+ex.Message+" 请求Url:" + this.Request.Url, "-2", Global.LogsDongleDomainList);
  62. }
  63. finally
  64. {
  65. System.Threading.Thread.Sleep(1);
  66. Response.End();
  67. }
  68. }
  69. /// <summary>
  70. /// 客户请求缓存集合
  71. /// </summary>
  72. static Dictionary<string, ClientRequestCache> ClientRequestCacheList = new Dictionary<string, ClientRequestCache>();
  73. /// <summary>
  74. /// 添加客户请求缓存
  75. /// </summary>
  76. /// <param name="crCache"></param>
  77. static void AddClientRequestCache(ClientRequestCache crCache)
  78. {
  79. lock (ClientRequestCacheList)
  80. {
  81. LYFZ.WXLibrary.ClientRequestCache RequestCache = null;
  82. if (ClientRequestCacheList.ContainsKey(crCache.Key))
  83. {
  84. RequestCache = ClientRequestCacheList[crCache.Key];
  85. RequestCache.RequestCount++;
  86. }
  87. else
  88. {
  89. ClientRequestCacheList.Add(crCache.Key, crCache);
  90. }
  91. }
  92. }
  93. /// <summary>
  94. /// 移除客户请求
  95. /// </summary>
  96. /// <param name="key"></param>
  97. static void RemoveClientRequestCache()
  98. {
  99. List<string> delCacheKeyList = new List<string>();
  100. lock (ClientRequestCacheList)
  101. {
  102. foreach (ClientRequestCache crCache in ClientRequestCacheList.Values)
  103. {
  104. if (crCache.RequestTime > DateTime.Now.AddMilliseconds(-30))
  105. {
  106. delCacheKeyList.Add(crCache.Key);
  107. }
  108. }
  109. if (delCacheKeyList.Count > 0)
  110. {
  111. foreach (string key in delCacheKeyList)
  112. {
  113. ClientRequestCacheList.Remove(key);
  114. }
  115. delCacheKeyList.Clear();
  116. delCacheKeyList = null;
  117. System.GC.Collect();
  118. }
  119. }
  120. }
  121. /// <summary>
  122. /// 获取客户请求
  123. /// </summary>
  124. /// <param name="key"></param>
  125. /// <returns></returns>
  126. static ClientRequestCache GetClientRequestCache(string key)
  127. {
  128. LYFZ.WXLibrary.ClientRequestCache RequestCache = null;
  129. lock (ClientRequestCacheList)
  130. {
  131. if (ClientRequestCacheList.ContainsKey(key))
  132. {
  133. RequestCache = ClientRequestCacheList[key];
  134. return RequestCache;
  135. }
  136. else
  137. {
  138. return null;
  139. }
  140. }
  141. }
  142. /// <summary>
  143. /// 新版开放平台接口请求处理
  144. /// Url:http://localhost:8086/WeiXinAPP/WXService.aspx?
  145. /// appid=/wx570bc396a51b8ff8
  146. /// &signature=b8c09dacd2f78ab91c66e671bbafedc7a8214585×
  147. /// tamp=1463793056
  148. /// &nonce=1644617734
  149. /// &encrypt_type=aes
  150. /// &msg_signature=9a1f16de1078d3727c51fcd0a8c5527441bd4cc8
  151. /// </summary>
  152. void OpenPlatformRetqusetHandle()
  153. {
  154. string appid = Request["appid"].ToString().Trim().Trim('/');
  155. string signature = Request["signature"];
  156. string timestamp = Request["timestamp"];
  157. string nonce = Request["nonce"];
  158. // string echostr = Request["echostr"];
  159. try
  160. {
  161. LYFZ.WXLibrary.CommonHandleClass.WriteLog("开如处理公众号AppID:" + appid + "的请求,Url:" + this.Request.Url, appid, Global.LogsDongleDomainList);
  162. }
  163. catch { }
  164. try
  165. {
  166. //获取当前公众号AppID的处理对象
  167. LYFZ.WXLibrary.AuthorizedAPPIDHandle APPIDHandle = null;
  168. if (OpenPlatformConfig.AuthorizedAPPIDHandleList.ContainsKey(appid))
  169. {
  170. APPIDHandle = OpenPlatformConfig.AuthorizedAPPIDHandleList[appid];
  171. JMGDomainName = APPIDHandle.JMGDomainName;
  172. LYFZ.WXLibrary.CommonHandleClass.WriteLog("公众号AppID:" + appid + "对应的标识符:" + JMGDomainName, appid, Global.LogsDongleDomainList);
  173. if (Request.HttpMethod == "GET")
  174. {
  175. WriteContent("标识符:" + JMGDomainName + ",如果你在浏览器中看到这句话,说明此微信公众账号已经成功授权,可以正常使用我们提供的相关功能。");
  176. }
  177. else
  178. {
  179. WeixinMessage message = null;
  180. var safeMode = Request.QueryString.Get("encrypt_type") == "aes";
  181. var postDataDocument = "";//new XDocument();// LYFZ.Weixin.SDK.Helpers.XmlUtility.Convert(Request.InputStream);
  182. try
  183. {
  184. Request.InputStream.Seek(0, SeekOrigin.Begin);//强制调整指针位置
  185. using (var streamReader = new StreamReader(Request.InputStream))
  186. {
  187. var decryptMsg = string.Empty;
  188. var msg = streamReader.ReadToEnd();
  189. #region 解密
  190. if (safeMode)
  191. {
  192. var msg_signature = Request.QueryString.Get("msg_signature");
  193. var wxBizMsgCrypt = new Tencent.WXBizMsgCrypt(OpenPlatformConfig.OpenToken, OpenPlatformConfig.OpenEncodingAESKey, OpenPlatformConfig.OpenAppID);
  194. var ret = wxBizMsgCrypt.DecryptMsg(msg_signature, timestamp, nonce, msg, ref decryptMsg);
  195. if (ret != 0)//解密失败
  196. {
  197. //TODO:开发者解密失败的业务处理逻辑
  198. LYFZ.WXLibrary.CommonHandleClass.WriteLog(string.Format("新版开放平台接口解密失败,解密消息返回{0},密文为:{1}", ret, msg));
  199. }
  200. }
  201. else
  202. {
  203. decryptMsg = msg;
  204. }
  205. #endregion
  206. //postDataDocument.(decryptMsg);
  207. LYFZ.WXLibrary.CommonHandleClass.WriteLog("POST 请求解密后的信息:" + decryptMsg, appid, Global.LogsDongleDomainList);
  208. message = AcceptMessageAPI.Parse(decryptMsg);
  209. postDataDocument = decryptMsg;//XDocument.Parse(encryptMsg);
  210. }
  211. }
  212. catch (Exception ex)
  213. {
  214. LYFZ.WXLibrary.CommonHandleClass.WriteLog("POST 请求加密解密时出错:" + ex.Message, appid, Global.LogsDongleDomainList);
  215. }
  216. if (message != null)
  217. {
  218. RemoveClientRequestCache();
  219. ClientRequestCache crCache = new ClientRequestCache(appid, message);
  220. AddClientRequestCache(crCache);
  221. string openId = message.Body.FromUserName.Value.ToString();
  222. string myUserName = message.Body.ToUserName.Value.ToString();
  223. if (appid.ToLower().Trim() == OpenPlatformConfig.MicroLetterTestAPPID.ToLower().Trim())
  224. {
  225. //微信后台专用测试公众号APPID 在全网发布时使用
  226. LYFZ.WXLibrary.CommonHandleClass.WriteLog("POST 请求开始处理微信后台专用(全网发布)测试", "-2", Global.LogsDongleDomainList);
  227. switch (message.Type)
  228. {
  229. case WeixinMessageType.Text:
  230. string Content = message.Body.Content.Value.ToString();
  231. if (Content.Contains("QUERY_AUTH_CODE:"))
  232. {
  233. //发送Api文本消息
  234. bool apisend = LYFZ.Weixin.SDK.ReplayActiveMessageAPI.RepayText(APPIDHandle.Authorizer_access_token, openId, Content.Split(':')[1] + "_from_api");
  235. LYFZ.WXLibrary.CommonHandleClass.WriteLog("微信后台专用(全网发布)测试 => 发送Api文本消息:" + apisend.ToString(), appid, Global.LogsDongleDomainList);
  236. WriteContent("");
  237. }
  238. else if (Content.Contains("TESTCOMPONENT_MSG_TYPE_TEXT"))
  239. {
  240. //回复普通文本消息
  241. string replayMsg = ReplayPassiveMessageAPI.RepayText(openId, myUserName, "TESTCOMPONENT_MSG_TYPE_TEXT_callback");
  242. LYFZ.WXLibrary.CommonHandleClass.WriteLog("微信后台专用(全网发布)测试 => 回复普通文本消息:" + replayMsg, appid, Global.LogsDongleDomainList);
  243. RepayTextMsg(safeMode, replayMsg, signature, timestamp, nonce);
  244. }
  245. break;
  246. case WeixinMessageType.Event:
  247. //发送事件消息
  248. string eventValue = message.Body.Event.Value.ToString();
  249. bool eventsend = LYFZ.Weixin.SDK.ReplayActiveMessageAPI.RepayText(APPIDHandle.Authorizer_access_token, openId, eventValue + "from_callback");
  250. LYFZ.WXLibrary.CommonHandleClass.WriteLog("微信后台专用(全网发布)测试 => 发送事件消息:" + eventsend.ToString(), appid, Global.LogsDongleDomainList);
  251. WriteContent("");
  252. break;
  253. }
  254. }
  255. else
  256. {
  257. string response = new LYFZ.WXLibrary.WeixinExecutor().ServiceExecute(message).ToLower().Trim();
  258. LYFZ.WXLibrary.CommonHandleClass.WriteLog("POST 当前事件值:" + response, appid, Global.LogsDongleDomainList);
  259. //获取客户接口配置信息
  260. LYFZ.WeixinServiceDate.Model.Model_CustomerInterfaces cusModel = Global.GetCustomerModel(JMGDomainName);
  261. if (cusModel != null && cusModel.ID > 0)
  262. {
  263. requestUrl = cusModel.GetRequestUrl();
  264. /* string newSignature = ""; //新的签名
  265. if (timestamp != null && nonce != null)
  266. {
  267. newSignature = BasicAPI.GetSignature(timestamp, nonce, cusModel.Token); //新的签名
  268. }*/
  269. string replayMsg = "";
  270. if (LYFZ.WXLibrary.CommonHandleClass.MicroLetterEventList.Contains(response))
  271. {
  272. ClientRequestCache currentRequestCache = GetClientRequestCache(crCache.Key);
  273. if (currentRequestCache.RequestCount < 3)
  274. {
  275. try
  276. {
  277. string functionCode = LYFZ.WXLibrary.CommonHandleClass.GetFunctionCode(response);
  278. LYFZ.WXLibrary.CommonHandleClass.WriteLog("公众号AppID:" + appid + "请求功能代码:" + functionCode, appid, Global.LogsDongleDomainList);
  279. try
  280. {
  281. string content = message.Body.Content.Value.ToString();
  282. LYFZ.WXLibrary.CommonHandleClass.WriteLog("提交的内容" + content, appid, Global.LogsDongleDomainList);
  283. if (content.Split('#').Length > 1)
  284. {
  285. replayMsg = MicroMessageProcessing.WeiXinMessageFastData(functionCode, content, openId, requestUrl, cusModel.ID, appid);
  286. }
  287. else
  288. {
  289. replayMsg = MicroMessageProcessing.WeiXinMessageData(functionCode, openId, requestUrl, cusModel.ID, appid);
  290. }
  291. }
  292. catch
  293. {
  294. replayMsg = MicroMessageProcessing.WeiXinMessageData(functionCode, openId, requestUrl, cusModel.ID, appid);
  295. }
  296. LYFZ.WXLibrary.CommonHandleClass.WriteLog("公众号AppID:" + appid + "请求“" + requestUrl + "”返回信息:" + replayMsg, appid, Global.LogsDongleDomainList);
  297. replayMsg = ReplayPassiveMessageAPI.RepayText(openId, myUserName, replayMsg);
  298. LYFZ.WXLibrary.CommonHandleClass.WriteLog("公众号AppID:" + appid + "请求“" + requestUrl + "”XML格式化后信息:" + replayMsg, appid, Global.LogsDongleDomainList);
  299. }
  300. catch (Exception ex)
  301. {
  302. replayMsg = "";
  303. LYFZ.WXLibrary.CommonHandleClass.WriteLog("在请求公众号AppID:" + appid + "的信息出错:" + ex.Message, appid, Global.LogsDongleDomainList);
  304. }
  305. }
  306. else
  307. {
  308. LYFZ.WXLibrary.CommonHandleClass.WriteLog("获取当前公众号AppID:" + appid + "的请求超时<br /> Url=" + requestUrl.Trim(), appid, Global.LogsDongleDomainList);
  309. replayMsg = "";
  310. }
  311. }
  312. else if (OpenPlatformConfig.IsTransmitService(response))
  313. {
  314. replayMsg = ReplayPassiveMessageAPI.TransmitService(openId, myUserName);
  315. LYFZ.WXLibrary.CommonHandleClass.WriteLog("公众号AppID:" + appid + "的信息已转到多客服:" + response, appid, Global.LogsDongleDomainList);
  316. }
  317. else
  318. {
  319. replayMsg = "";//ReplayPassiveMessageAPI.RepayText(openId, myUserName, "收到的信息:" + response);
  320. LYFZ.WXLibrary.CommonHandleClass.WriteLog("非法指令请求 公众号AppID:" + appid + "对应的标识:" + JMGDomainName + "收到的信息:" + response, appid, Global.LogsDongleDomainList);
  321. }
  322. if (!String.IsNullOrEmpty(replayMsg))
  323. {
  324. RepayTextMsg(safeMode, replayMsg, signature, timestamp, nonce);
  325. }
  326. else
  327. {
  328. LYFZ.WXLibrary.CommonHandleClass.WriteLog("当前公众号AppID:" + appid + "的返回信息为空", appid, Global.LogsDongleDomainList);
  329. WriteContent("");
  330. }
  331. }
  332. else
  333. {
  334. LYFZ.WXLibrary.CommonHandleClass.WriteLog("获取当前公众号AppID:" + appid + "的客户接口配置信息失败", appid, Global.LogsDongleDomainList);
  335. WriteContent("");
  336. }
  337. }
  338. }
  339. else
  340. {
  341. LYFZ.WXLibrary.CommonHandleClass.WriteLog("获取当前公众号AppID:" + appid + "的客户接口配置信息失败", appid, Global.LogsDongleDomainList);
  342. WriteContent("");
  343. }
  344. }
  345. }
  346. else
  347. {
  348. LYFZ.WXLibrary.CommonHandleClass.WriteLog("获取当前公众号AppID:" + appid + "的处理对象失败", appid, Global.LogsDongleDomainList);
  349. WriteContent("");
  350. }
  351. }
  352. catch (Exception ex)
  353. {
  354. LYFZ.WXLibrary.CommonHandleClass.WriteLog("处理当前公众号AppID:" + appid + "信息时出错:" + ex.Message, appid, Global.LogsDongleDomainList);
  355. WriteContent("");
  356. }
  357. }
  358. void RepayTextMsg(bool safeMode, string replayMsg, string signature, string timestamp, string nonce)
  359. {
  360. string encryptMsg = replayMsg;
  361. if (safeMode)
  362. {
  363. var msg_signature = Request.QueryString.Get("msg_signature");
  364. var wxBizMsgCrypt = new Tencent.WXBizMsgCrypt(OpenPlatformConfig.OpenToken, OpenPlatformConfig.OpenEncodingAESKey, OpenPlatformConfig.OpenAppID);
  365. var ret = wxBizMsgCrypt.EncryptMsg(replayMsg, timestamp, nonce, ref encryptMsg);
  366. if (ret != 0)//加密失败
  367. {
  368. //TODO:开发者加密失败的业务处理逻辑
  369. LYFZ.WXLibrary.CommonHandleClass.WriteLog(string.Format("加密失败,加密消息返回{0},响应体{1}", ret, encryptMsg), "-2", Global.LogsDongleDomainList);
  370. }
  371. else
  372. {
  373. LYFZ.WXLibrary.CommonHandleClass.WriteLog(string.Format("加密成功,加密前的消息{0}", replayMsg), "-2", Global.LogsDongleDomainList);
  374. LYFZ.WXLibrary.CommonHandleClass.WriteLog(string.Format("加密成功,加密后的消息{0}", encryptMsg), "-2", Global.LogsDongleDomainList);
  375. }
  376. }
  377. WriteContent(encryptMsg);
  378. }
  379. public static string getUrlQueryString(System.Collections.Specialized.NameValueCollection query)
  380. {
  381. string retUrlQueryString = "";
  382. foreach (string key in query.AllKeys)
  383. {
  384. if (key != null && key.ToLower() != "requestUrl".ToLower() && key.ToLower() != "yuname")
  385. {
  386. string[] values = query.GetValues(key);
  387. foreach (string value in values)
  388. {
  389. retUrlQueryString += key + "=" + value + "&";
  390. }
  391. }
  392. }
  393. return retUrlQueryString.Trim('&');
  394. }
  395. public static string getRequestUrl(string url, string parameters)
  396. {
  397. if (parameters.Length > 0)
  398. {
  399. if (url.Contains("?"))
  400. {
  401. return url + "&" + parameters.Trim('&');
  402. }
  403. else
  404. {
  405. return url + "?" + parameters.Trim('&');
  406. }
  407. }
  408. else
  409. {
  410. return url;
  411. }
  412. }
  413. private void WriteContent(string str)
  414. {
  415. try
  416. {
  417. if (!str.ToLower().Contains("Request failed,Exception:".ToLower()) && !str.Contains("Url参数错误"))
  418. {
  419. Global.UpdateCustCallFrequency(JMGDomainName);
  420. }
  421. }
  422. catch { }
  423. // Response.Output.Write(str);
  424. Response.Write(str);
  425. }
  426. #region Web GET POST方式提交
  427. /// <summary>
  428. /// Web POST方式提交
  429. /// </summary>
  430. /// <param name="url"></param>
  431. /// <param name="postData"></param>
  432. /// <returns></returns>
  433. public static string HttpWebRequestPOST(string url, string postData)
  434. {
  435. if (url.Trim().Length > 1)
  436. {
  437. return LYFZ.WinAPI.CustomPublicMethod.HttpWebRequestPOST(url, postData, Encoding.UTF8, "text/xml");
  438. }
  439. else
  440. {
  441. return "Url参数错误";
  442. }
  443. }
  444. /// <summary>
  445. /// Web GET方式提交
  446. /// </summary>
  447. /// <param name="url"></param>
  448. /// <returns></returns>
  449. public static string HttpWebRequestGET(string url)
  450. {
  451. if (url.Trim().Length > 1)
  452. {
  453. return LYFZ.WinAPI.CustomPublicMethod.HttpWebRequestGET(url, Encoding.UTF8);
  454. }
  455. else
  456. {
  457. return "Url参数错误";
  458. }
  459. }
  460. #endregion
  461. }
  462. }