WXService.aspx.cs 25 KB

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