• .net实现微信公众账号接口开发


    说起微信公众帐号,大家都不会陌生,使用这个平台能给网站或系统增加一个新亮点,直接进入正题吧,在使用之前一定要仔细阅读官方API文档。

    API文档地址:http://mp.weixin.qq.com/wiki/index.php
     
    使用.net实现的方法:

    //微信接口地址 页面代码:

    1. weixin _wx = new weixin();  
    2. string postStr = "";  
    3. if (Request.HttpMethod.ToLower() == "post")  
    4. {  
    5. Stream s = System.Web.HttpContext.Current.Request.InputStream;  
    6. byte[] b = new byte[s.Length];  
    7. s.Read(b, 0, (int)s.Length);  
    8. postStr = Encoding.UTF8.GetString(b);  
    9. if (!string.IsNullOrEmpty(postStr)) //请求处理  
    10. {  
    11. _wx.Handle(postStr);   
    12. }  
    13. }  
    14. else 
    15. {  
    16. _wx.Auth();  

    具体处理类

    1. /// <summary>  
    2. /// 微信公众平台操作类  
    3. /// </summary>  
    4. public class weixin  
    5. {  
    6. private string Token = "my_weixin_token"; //换成自己的token  
    7. public void Auth()  
    8. {  
    9. string echoStr = System.Web.HttpContext.Current.Request.QueryString["echoStr"];  
    10. if (CheckSignature()) //校验签名是否正确  
    11. {  
    12. if (!string.IsNullOrEmpty(echoStr))  
    13. {  
    14. System.Web.HttpContext.Current.Response.Write(echoStr); //返回原值表示校验成功  
    15. System.Web.HttpContext.Current.Response.End();  
    16. }  
    17. }  
    18. }  
    19.  
    20.  
    21. public void Handle(string postStr)  
    22. {  
    23. //封装请求类  
    24. XmlDocument doc = new XmlDocument();  
    25. doc.LoadXml(postStr);  
    26. XmlElement rootElement = doc.DocumentElement;  
    27. //MsgType  
    28. XmlNode MsgType = rootElement.SelectSingleNode("MsgType");  
    29. //接收的值--->接收消息类(也称为消息推送)  
    30. RequestXML requestXML = new RequestXML();  
    31. requestXML.ToUserName = rootElement.SelectSingleNode("ToUserName").InnerText;  
    32. requestXML.FromUserName = rootElement.SelectSingleNode("FromUserName").InnerText;  
    33. requestXML.CreateTime = rootElement.SelectSingleNode("CreateTime").InnerText;  
    34. requestXML.MsgType = MsgType.InnerText;  
    35.  
    36. //根据不同的类型进行不同的处理  
    37. switch (requestXML.MsgType)  
    38. {  
    39. case "text": //文本消息  
    40. requestXML.Content = rootElement.SelectSingleNode("Content").InnerText;  
    41. break;  
    42. case "image": //图片  
    43. requestXML.PicUrl = rootElement.SelectSingleNode("PicUrl").InnerText;  
    44. break;  
    45. case "location": //位置  
    46. requestXML.Location_X = rootElement.SelectSingleNode("Location_X").InnerText;  
    47. requestXML.Location_Y = rootElement.SelectSingleNode("Location_Y").InnerText;  
    48. requestXML.Scale = rootElement.SelectSingleNode("Scale").InnerText;  
    49. requestXML.Label = rootElement.SelectSingleNode("Label").InnerText;  
    50. break;  
    51. case "link": //链接  
    52. break;  
    53. case "event": //事件推送 支持V4.5+  
    54. break;  
    55. }  
    56.  
    57. //消息回复  
    58. ResponseMsg(requestXML);  
    59. }  
    60.  
    61.  
    62. /// <summary>  
    63. /// 验证微信签名  
    64. /// * 将token、timestamp、nonce三个参数进行字典序排序  
    65. /// * 将三个参数字符串拼接成一个字符串进行sha1加密  
    66. /// * 开发者获得加密后的字符串可与signature对比,标识该请求来源于微信。  
    67. /// </summary>  
    68. /// <returns></returns>  
    69. private bool CheckSignature()  
    70. {  
    71. string signature = System.Web.HttpContext.Current.Request.QueryString["signature"];  
    72. string timestamp = System.Web.HttpContext.Current.Request.QueryString["timestamp"];  
    73. string nonce = System.Web.HttpContext.Current.Request.QueryString["nonce"];  
    74. //加密/校验流程:  
    75. //1. 将token、timestamp、nonce三个参数进行字典序排序  
    76. string[] ArrTmp = { Token, timestamp, nonce };   
    77. Array.Sort(ArrTmp);//字典排序  
    78. //2.将三个参数字符串拼接成一个字符串进行sha1加密  
    79. string tmpStr = string.Join("", ArrTmp);  
    80. tmpStr = FormsAuthentication.HashPasswordForStoringInConfigFile(tmpStr, "SHA1");  
    81. tmpStr = tmpStr.ToLower();  
    82. //3.开发者获得加密后的字符串可与signature对比,标识该请求来源于微信。  
    83. if (tmpStr == signature)  
    84. {  
    85. return true;  
    86. }  
    87. else 
    88. {  
    89. return false;  
    90. }  
    91. }  
    92.  
    93. /// <summary>  
    94. /// 消息回复(微信信息返回)  
    95. /// </summary>  
    96. /// <param name="requestXML">The request XML.</param>  
    97. private void ResponseMsg(RequestXML requestXML)  
    98. {  
    99. try 
    100. {  
    101. string resxml = "";  
    102. //主要是调用数据库进行关键词匹配自动回复内容,可以根据自己的业务情况编写。  
    103. //1.通常有,没有匹配任何指令时,返回帮助信息  
    104. AutoResponse mi = new AutoResponse(requestXML.Content, requestXML.FromUserName);  
    105.  
    106. switch (requestXML.MsgType)  
    107. {  
    108. case "text":  
    109. //在这里执行一系列操作,从而实现自动回复内容.   
    110. string _reMsg = mi.GetReMsg();  
    111. if (mi.msgType == 1)  
    112. {  
    113. resxml = "<xml><ToUserName><![CDATA[" + requestXML.FromUserName + "]]></ToUserName><FromUserName><![CDATA[" + requestXML.ToUserName + "]]></FromUserName><CreateTime>" + ConvertDateTimeInt(DateTime.Now) + "</CreateTime><MsgType><![CDATA[news]]></MsgType><Content><![CDATA[]]></Content><ArticleCount>2</ArticleCount><Articles>";  
    114. resxml += mi.GetRePic(requestXML.FromUserName);  
    115. resxml += "</Articles><FuncFlag>1</FuncFlag></xml>";  
    116. }  
    117. else 
    118. {  
    119. resxml = "<xml><ToUserName><![CDATA[" + requestXML.FromUserName + "]]></ToUserName><FromUserName><![CDATA[" + requestXML.ToUserName + "]]></FromUserName><CreateTime>" + ConvertDateTimeInt(DateTime.Now) + "</CreateTime><MsgType><![CDATA[text]]></MsgType><Content><![CDATA[" + _reMsg + "]]></Content><FuncFlag>1</FuncFlag></xml>";  
    120. }  
    121. break;  
    122. case "location":  
    123. string city = GetMapInfo(requestXML.Location_X, requestXML.Location_Y);  
    124. if (city == "0")  
    125. {  
    126. resxml = "<xml><ToUserName><![CDATA[" + requestXML.FromUserName + "]]></ToUserName><FromUserName><![CDATA[" + requestXML.ToUserName + "]]></FromUserName><CreateTime>" + ConvertDateTimeInt(DateTime.Now) + "</CreateTime><MsgType><![CDATA[text]]></MsgType><Content><![CDATA[好啦,我们知道您的位置啦。您可以:" + mi.GetDefault() + "]]></Content><FuncFlag>1</FuncFlag></xml>";  
    127. }  
    128. else 
    129. {  
    130. resxml = "<xml><ToUserName><![CDATA[" + requestXML.FromUserName + "]]></ToUserName><FromUserName><![CDATA[" + requestXML.ToUserName + "]]></FromUserName><CreateTime>" + ConvertDateTimeInt(DateTime.Now) + "</CreateTime><MsgType><![CDATA[text]]></MsgType><Content><![CDATA[好啦,我们知道您的位置啦。您可以:" + mi.GetDefault() + "]]></Content><FuncFlag>1</FuncFlag></xml>";  
    131. }  
    132. break;  
    133. case "image":  
    134. //图文混合的消息 具体格式请见官方API“回复图文消息”   
    135. break;  
    136. }  
    137.  
    138. System.Web.HttpContext.Current.Response.Write(resxml);  
    139. WriteToDB(requestXML, resxml, mi.pid);  
    140. }  
    141. catch (Exception ex)  
    142. {  
    143. //WriteTxt("异常:" + ex.Message + "Struck:" + ex.StackTrace.ToString());  
    144. //wx_logs.MyInsert("异常:" + ex.Message + "Struck:" + ex.StackTrace.ToString());  
    145. }  
    146. }  
    147.  
    148.  
    149. /// <summary>  
    150. /// unix时间转换为datetime  
    151. /// </summary>  
    152. /// <param name="timeStamp"></param>  
    153. /// <returns></returns>  
    154. private DateTime UnixTimeToTime(string timeStamp)  
    155. {  
    156. DateTime dtStart = TimeZone.CurrentTimeZone.ToLocalTime(new DateTime(1970, 1, 1));  
    157. long lTime = long.Parse(timeStamp + "0000000");  
    158. TimeSpan toNow = new TimeSpan(lTime);  
    159. return dtStart.Add(toNow);  
    160. }  
    161.  
    162.  
    163. /// <summary>  
    164. /// datetime转换为unixtime  
    165. /// </summary>  
    166. /// <param name="time"></param>  
    167. /// <returns></returns>  
    168. private int ConvertDateTimeInt(System.DateTime time)  
    169. {  
    170. System.DateTime startTime = TimeZone.CurrentTimeZone.ToLocalTime(new System.DateTime(1970, 1, 1));  
    171. return (int)(time - startTime).TotalSeconds;  
    172. }  
    173.  
    174.  
    175. /// <summary>  
    176. /// 调用百度地图,返回坐标信息  
    177. /// </summary>  
    178. /// <param name="y">经度</param>  
    179. /// <param name="x">纬度</param>  
    180. /// <returns></returns>  
    181. public string GetMapInfo(string x, string y)  
    182. {  
    183. try 
    184. {  
    185. string res = string.Empty;  
    186. string parame = string.Empty;  
    187. string url = "http://maps.googleapis.com/maps/api/geocode/xml";  
    188.  
    189. parame = "latlng=" + x + "," + y + "&language=zh-CN&sensor=false";//此key为个人申请  
    190. res = webRequestPost(url, parame);  
    191.  
    192. XmlDocument doc = new XmlDocument();  
    193. doc.LoadXml(res);  
    194.  
    195. XmlElement rootElement = doc.DocumentElement;  
    196. string Status = rootElement.SelectSingleNode("status").InnerText;  
    197.  
    198. if (Status == "OK")  
    199. {  
    200. //仅获取城市  
    201. XmlNodeList xmlResults = rootElement.SelectSingleNode("/GeocodeResponse").ChildNodes;  
    202. for (int i = 0; i < xmlResults.Count; i++)  
    203. {  
    204. XmlNode childNode = xmlResults[i];  
    205. if (childNode.Name == "status") {  
    206. continue;  
    207. }  
    208. string city = "0";  
    209. for (int w = 0; w < childNode.ChildNodes.Count; w++)  
    210. {  
    211. for (int q = 0; q < childNode.ChildNodes[w].ChildNodes.Count; q++)  
    212. {  
    213. XmlNode childeTwo = childNode.ChildNodes[w].ChildNodes[q];  
    214. if (childeTwo.Name == "long_name")  
    215. {  
    216. city = childeTwo.InnerText;  
    217. }  
    218. else if (childeTwo.InnerText == "locality")  
    219. {  
    220. return city;  
    221. }  
    222. }  
    223. }  
    224. return city;  
    225. }  
    226. }  
    227. }  
    228. catch (Exception ex)  
    229. {  
    230. //WriteTxt("map异常:" + ex.Message.ToString() + "Struck:" + ex.StackTrace.ToString());  
    231. return "0";  
    232. }   
    233. return "0";  
    234. }  
    235.  
    236.  
    237. /// <summary>  
    238. /// Post 提交调用抓取  
    239. /// </summary>  
    240. /// <param name="url">提交地址</param>  
    241. /// <param name="param">参数</param>  
    242. /// <returns>string</returns>  
    243. public string webRequestPost(string url, string param)  
    244. {  
    245. byte[] bs = System.Text.Encoding.UTF8.GetBytes(param);  
    246. HttpWebRequest req = (HttpWebRequest)HttpWebRequest.Create(url + "?" + param);  
    247. req.Method = "Post";  
    248. req.Timeout = 120 * 1000;  
    249. req.ContentType = "application/x-www-form-urlencoded;";  
    250. req.ContentLength = bs.Length;  
    251.  
    252. using (Stream reqStream = req.GetRequestStream())  
    253. {  
    254. reqStream.Write(bs, 0, bs.Length);  
    255. reqStream.Flush();  
    256. }  
    257.  
    258. using (WebResponse wr = req.GetResponse())  
    259. {  
    260. //在这里对接收到的页面内容进行处理  
    261. Stream strm = wr.GetResponseStream();  
    262. StreamReader sr = new StreamReader(strm, System.Text.Encoding.UTF8);  
    263.  
    264. string line;  
    265. System.Text.StringBuilder sb = new System.Text.StringBuilder();  
    266. while ((line = sr.ReadLine()) != null)  
    267. {  
    268. sb.Append(line + System.Environment.NewLine);  
    269. }  
    270. sr.Close();  
    271. strm.Close();  
    272. return sb.ToString();  
    273. }  
    274. }  
    275.  
    276. /// <summary>  
    277. /// 将本次交互信息保存至数据库中  
    278. /// </summary>  
    279. /// <param name="requestXML"></param>  
    280. /// <param name="_xml"></param>  
    281. /// <param name="_pid"></param>  
    282. private void WriteToDB(RequestXML requestXML, string _xml, int _pid)  
    283. {  
    284. WeiXinMsg wx = new WeiXinMsg();  
    285. wx.FromUserName = requestXML.FromUserName;  
    286. wx.ToUserName = requestXML.ToUserName;  
    287. wx.MsgType = requestXML.MsgType;  
    288. wx.Msg = requestXML.Content;  
    289. wx.Creatime = requestXML.CreateTime;  
    290. wx.Location_X = requestXML.Location_X;  
    291. wx.Location_Y = requestXML.Location_Y;  
    292. wx.Label = requestXML.Label;  
    293. wx.Scale = requestXML.Scale;  
    294. wx.PicUrl = requestXML.PicUrl;  
    295. wx.reply = _xml;  
    296. wx.pid = _pid;  
    297. try 
    298. {  
    299. wx.Add();  
    300. }  
    301. catch (Exception ex)  
    302. {  
    303. //wx_logs.MyInsert(ex.Message);  
    304. //ex.message;  
    305. }  
    306. }  

    响应类MODEL

    1. #region 微信请求类 RequestXML  
    2. /// <summary>  
    3. /// 微信请求类  
    4. /// </summary>  
    5. public class RequestXML  
    6. {  
    7. private string toUserName = "";  
    8. /// <summary>  
    9. /// 消息接收方微信号,一般为公众平台账号微信号  
    10. /// </summary>  
    11. public string ToUserName  
    12. {  
    13. get { return toUserName; }  
    14. set { toUserName = value; }  
    15. }  
    16.  
    17. private string fromUserName = "";  
    18. /// <summary>  
    19. /// 消息发送方微信号  
    20. /// </summary>  
    21. public string FromUserName  
    22. {  
    23. get { return fromUserName; }  
    24. set { fromUserName = value; }  
    25. }  
    26.  
    27. private string createTime = "";  
    28. /// <summary>  
    29. /// 创建时间  
    30. /// </summary>  
    31. public string CreateTime  
    32. {  
    33. get { return createTime; }  
    34. set { createTime = value; }  
    35. }  
    36.  
    37. private string msgType = "";  
    38. /// <summary>  
    39. /// 信息类型 地理位置:location,文本消息:text,消息类型:image  
    40. /// </summary>  
    41. public string MsgType  
    42. {  
    43. get { return msgType; }  
    44. set { msgType = value; }  
    45. }  
    46.  
    47. private string content = "";  
    48. /// <summary>  
    49. /// 信息内容  
    50. /// </summary>  
    51. public string Content  
    52. {  
    53. get { return content; }  
    54. set { content = value; }  
    55. }  
    56.  
    57. private string location_X = "";  
    58. /// <summary>  
    59. /// 地理位置纬度  
    60. /// </summary>  
    61. public string Location_X  
    62. {  
    63. get { return location_X; }  
    64. set { location_X = value; }  
    65. }  
    66.  
    67. private string location_Y = "";  
    68. /// <summary>  
    69. /// 地理位置经度  
    70. /// </summary>  
    71. public string Location_Y  
    72. {  
    73. get { return location_Y; }  
    74. set { location_Y = value; }  
    75. }  
    76.  
    77. private string scale = "";  
    78. /// <summary>  
    79. /// 地图缩放大小  
    80. /// </summary>  
    81. public string Scale  
    82. {  
    83. get { return scale; }  
    84. set { scale = value; }  
    85. }  
    86.  
    87. private string label = "";  
    88. /// <summary>  
    89. /// 地理位置信息  
    90. /// </summary>  
    91. public string Label  
    92. {  
    93. get { return label; }  
    94. set { label = value; }  
    95. }  
    96.  
    97. private string picUrl = "";  
    98. /// <summary>  
    99. /// 图片链接,开发者可以用HTTP GET获取  
    100. /// </summary>  
    101. public string PicUrl  
    102. {  
    103. get { return picUrl; }  
    104. set { picUrl = value; }  
    105. }  
    106. }  
    107. #endregion 
  • 相关阅读:
    1.1 Introduction中 Apache Kafka™ is a distributed streaming platform. What exactly does that mean?(官网剖析)(博主推荐)
    Android 涂鸦最佳实践
    使用 stvd 编译STM8S 时能看到使用RAM ROM大小的方法
    【四】注入框架RoboGuice使用:(Your First System Service Injection)
    让演示样例代码在手机上换行显示
    归并排序算法
    HDU 1573 X问题 中国剩余定理
    【leetcode】6. ZigZag Conversion
    sdfs
    翻转句子中单词的顺序 C语言
  • 原文地址:https://www.cnblogs.com/Alex80/p/4236058.html
Copyright © 2020-2023  润新知