·您现在的位置: 云翼网络 >> 文章中心 >> 网站建设 >> 网站建设开发 >> ASP.NET网站开发 >> C# asp.net 搭建微信公众平台(可实现关注消息与消息自动回复)的代码以及我所遇到的问题

C# asp.net 搭建微信公众平台(可实现关注消息与消息自动回复)的代码以及我所遇到的问题

作者:佚名      ASP.NET网站开发编辑:admin      更新时间:2022-07-23

C# asp.net 搭建微信公众平台(可实现关注消息与消息自动回复)的代码以及我所遇到的问题

【引言】

   利用asp.net搭建微信公众平台的案例并不多,微信官方给的案例是用php的,网上能找到的代码很多也是存在着这样那样的问题或者缺少部分方法,无法使用,下面是我依照官方文档写的基于.net 搭建微信公众平台源代码。由于经验不足,内可能存在不严谨之处,欢迎交流。

【分析】

   实现的功能较为简单,主要分为验证与消息接收回复两部分,首先是验证:

  

  这已经是验证好后的截图了,需要输入的是URL和你自己设定的Token码,URL为你上传服务器的地址例如:http://XXXXX.com/weixin/weixin.aspx,这里着重要强调的一个问题是加不加WWW的差异,无论加不加WWW,在验证时都是没有影响的,但在接收消息时,加和不加的差异是我最初无法接收到用户消息的直接原因,原因可能和POST带xml的请求机制有关。落实到具体项目中加还是不加,和你配置的DNS等有关,要是不想深入研究,当接收不到用户消息,而公众平台的调试工具里又是正常的,那你可以交替试试。Token码可以随机指定,但必须和代码中的Token指定相同,如果系统安全性要求比较高,建议增加token的复杂程度。

  在下面代码第一行中指定token,必须与上面一直

 1      const string Token = "nidaye1234";//你的token 2         #region 以下代码只用于第一次验证  验证完后请注释 3         PRotected void Page_Load(object sender, EventArgs e) 4         { 5             string postStr = ""; 6             if (Request.HttpMethod.ToLower() == "post") 7             { 8                 System.IO.Stream s = System.Web.HttpContext.Current.Request.InputStream; 9                 byte[] b = new byte[s.Length];10                 s.Read(b, 0, (int)s.Length);11                 postStr = System.Text.Encoding.UTF8.GetString(b);12                 if (!string.IsNullOrEmpty(postStr))13                 {16                     Response.End();17                 }18                 //WriteLog("postStr:" + postStr);19             }20             else21             {22                 Valid();23             }24         } 25         #endregion

上面的代码只是pageLoad,里面还要调用到的验证方法这里先不写,在最后会给出全部的源代码。

  验证成功后可以调用api实现消息收发,下面是微信官方给的文档

  接收消息

  

  发送消息

  以及关注事件

  我的做法是首先创建一个接收消息实体以及实体填充方法,如下,其中根据MsgType的不同,选择填充合适的Content或者EventName。当然我这里没有使用微信为开发者提供的高级功能(例如语音定位之类的),如有用到可以增加这个类的属性,并对应修改填充器即可。

 1         private class ExmlMsg 2         { 3             /// <summary> 4             /// 本公众账号 5             /// </summary> 6             public string ToUserName { get; set; } 7             /// <summary> 8             /// 用户账号 9             /// </summary>10             public string FromUserName { get; set; }11             /// <summary>12             /// 发送时间戳13             /// </summary>14             public string CreateTime { get; set; }15             /// <summary>16             /// 发送的文本内容17             /// </summary>18             public string Content { get; set; }19             /// <summary>20             /// 消息的类型21             /// </summary>22             public string MsgType { get; set; }23             /// <summary>24             /// 事件名称25             /// </summary>26             public string EventName { get; set; } 27 28         }29 30         private ExmlMsg GetExmlMsg(XmlElement root) 31         {32             ExmlMsg xmlMsg = new ExmlMsg() {33                 FromUserName = root.SelectSingleNode("FromUserName").InnerText,34                 ToUserName = root.SelectSingleNode("ToUserName").InnerText,35                 CreateTime = root.SelectSingleNode("CreateTime").InnerText,36                 MsgType = root.SelectSingleNode("MsgType").InnerText,               37             };38             if (xmlMsg.MsgType.Trim().ToLower() == "text")39             {40                 xmlMsg.Content = root.SelectSingleNode("Content").InnerText;41             }42             else if (xmlMsg.MsgType.Trim().ToLower() == "event")43             {44                 xmlMsg.EventName = root.SelectSingleNode("Event").InnerText;45             }46             return xmlMsg;47         }

  普通使用时(非验证时)的pageload,这个方法主要通过调用PostInput()(详间最后的源代码)还获取post过来的数据,并将它们传入消息适配器中。

 1         /// <summary> 2         /// 以下是正常使用时的pageload  请在验证时将其注释  并保证在正常使用时可用 3         /// </summary> 4         /// <param name="sender"></param> 5         /// <param name="e"></param> 6         protected void Page_Load(object sender, EventArgs e) 7         { 8  9             if (Request.HttpMethod == "POST")10             {11                 string weixin = "";12                 weixin = PostInput();//获取xml数据13                 if (!string.IsNullOrEmpty(weixin))14                 {15                     ResponseMsg(weixin);////调用消息适配器16                 }17             }18         } 

  以下消息适配器,通过MsgType来区分消息的类型,并调用对应的方法,这里偷了一个懒,就是用户首次关注时推送消息的方法没有抽象出去,因为我暂时也没有别的enven可调用,如果结构复杂时,可以自行抽象。如果需要改变欢迎词的内容改变msg的值即可。日后扩展新功能时,可以根据case的的MsgType新写对应的方法,我这里主要用到的是textCase(),需要传入用户发送过来的消息实体,因为你的业务逻辑中可能需要用到发件者的各种信息。

 1        private void ResponseMsg(string weixin)// 服务器响应微信请求 2         { 3             XmlDocument doc = new XmlDocument(); 4             doc.LoadXml(weixin);//读取xml字符串 5             XmlElement root = doc.DocumentElement; 6             ExmlMsg xmlMsg = GetExmlMsg(root); 7             //XmlNode MsgType = root.SelectSingleNode("MsgType"); 8             //string messageType = MsgType.InnerText; 9             string messageType = xmlMsg.MsgType;//获取收到的消息类型。文本(text),图片(image),语音等。10 11   12             try13             {14                 15                 switch (messageType)16                 {17                     //当消息为文本时18                     case "text":19                         textCase(xmlMsg);20                         break;21                     case "event":22                         if (!string.IsNullOrEmpty(xmlMsg.EventName) && xmlMsg.EventName.Trim() == "subscribe")23                         {24                             //刚关注时的时间,用于欢迎词  25                             int nowtime = ConvertDateTimeInt(DateTime.Now);26                             string msg = "你要关注我,我有什么办法。随便发点什么试试吧~~~";27                             string resxml = "<xml><ToUserName><![CDATA[" + xmlMsg.FromUserName + "]]></ToUserName><FromUserName><![CDATA[" + xmlMsg.ToUserName + "]]></FromUserName><CreateTime>" + nowtime + "</CreateTime><MsgType><![CDATA[text]]></MsgType><Content><![CDATA[" + msg + "]]></Content><FuncFlag>0</FuncFlag></xml>";28                             Response.Write(resxml);29                         }30                         break;31                     case "image":32                         break;33                     case "voice":34                         break;35                     case "vedio":36                         break;37                     case "location":38                         break;39                     case "link":40                         break;41                     default:42                         break;43                 }44                 Response.End();45             }46             catch (Exception)47             {48 49             }50         } 

  获取文本回复信息方法,主要目的是按照官方文档的要求,拼接出所要返回给微信服务器的xml格式。它的msg内容来自于getText方法,同样需要传入用户消息实体,我下面给出了我用来测试的方法的内容。

1         private void textCase(ExmlMsg xmlMsg)2         {     3             int nowtime = ConvertDateTimeInt(DateTime.Now);4             string msg = "";5             msg = getText(xmlMsg);6             string resxml = "<xml><ToUserName><![CDATA[" + xmlMsg.FromUserName + "]]></ToUserName><FromUserName><![CDATA[" + xmlMsg.ToUserName + "]]></FromUserName><CreateTime>" + nowtim