【引言】
利用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
新聞熱點
疑難解答