經過了上一篇文章以後的微信開發者驗證以後,咱們就能夠作微信公衆號的代碼開發了。web
當咱們點擊關注某個公衆號的時候,有時候會發現他會自動給咱們回覆一條消息,好比歡迎關注XXX公衆號。這個功能實際上是在點擊關注的時候,用戶觸發了微信定義的事件,同時微信會返回給咱們一個XML數據包,微信官方的解釋以下:api
推送XML數據包示例:服務器
<xml> <ToUserName><![CDATA[toUser]]></ToUserName> <FromUserName><![CDATA[FromUser]]></FromUserName> <CreateTime>123456789</CreateTime> <MsgType><![CDATA[event]]></MsgType> <Event><![CDATA[subscribe]]></Event> </xml>
參數說明:微信
參數 | 描述 |
---|---|
ToUserName | 開發者微信號 |
FromUserName | 發送方賬號(一個OpenID) |
CreateTime | 消息建立時間 (整型) |
MsgType | 消息類型,event |
Event | 事件類型,subscribe(訂閱)、unsubscribe(取消訂閱) |
從示例中能夠看出,若是咱們想要處理用戶點擊的關注事件,那麼必需要知道消息類型MsgType,事件類型Event。因此咱們能夠仿照着微信給咱們的XML示例用C#創建一下事件接受的類,具體代碼以下:微信開發
public class wxmessage { /// <summary> /// 本公衆賬號 /// </summary> public string ToUserName { get; set; } /// <summary> /// 用戶賬號 /// </summary> public string FromUserName { get; set; } /// <summary> /// 發送時間戳 /// </summary> public string CreateTime { get; set; } /// <summary> /// 發送的文本內容 /// </summary> public string Content { get; set; } /// <summary> /// 消息的類型 /// </summary> public string MsgType { get; set; } /// <summary> /// 事件名稱 /// </summary> public string EventName { get; set; } //這兩個屬性會在後面的講解中提到 public string Recognition { get; set; } public string EventKey { get; set; } }
事件類創建完成以後,咱們就能夠在wxapi.aspx頁面中作事件處理的邏輯操做了,請看下面的代碼:app
public partial class wxapi : System.Web.UI.Page { const string _token = "在微信公衆測試號後臺寫的那個Token"; private const string _myOpenid = "你本身微信公衆測試號的appID"; string postStr = ""; protected void Page_Load(object sender, EventArgs e) { //************** 驗證成爲開發者的時候將此代碼註釋 ***********// //對微信的信息進行處理和應用 WXOpera(); //*********** 驗證成爲開發者以後將此代碼註釋 *************// //string httpMethod = Request.HttpMethod.ToLower(); //if (httpMethod == "post") //{ // //第一次驗證的時候開啓 // FirstValid(); //} //else //{ // Valid(); //若是不是post請求就去作開發者驗證 //} } /// <summary> /// 驗證成爲開發者 /// </summary> private void Valid() { string echoStr = Request.QueryString["echoStr"].ToString(); if (CheckSignature()) { if (!string.IsNullOrEmpty(echoStr)) { Response.Write(echoStr); Response.End(); } } } /// <summary> /// 驗證微信簽名 /// </summary> /// * 將token、timestamp、nonce三個參數進行字典序排序 /// * 將三個參數字符串拼接成一個字符串進行sha1加密 /// * 開發者得到加密後的字符串可與signature對比,標識該請求來源於微信。 /// <returns></returns> private bool CheckSignature() { string signature = Request.QueryString["signature"].ToString(); string timestamp = Request.QueryString["timestamp"].ToString(); string nonce = Request.QueryString["nonce"].ToString(); string[] ArrTmp = { _token, timestamp, nonce }; Array.Sort(ArrTmp); //字典排序 string tmpStr = string.Join("", ArrTmp); tmpStr = FormsAuthentication.HashPasswordForStoringInConfigFile(tmpStr, "SHA1"); tmpStr = tmpStr.ToLower(); if (tmpStr == signature) { return true; } else { return false; } } /// <summary> /// 第一次驗證配置 /// </summary> private void FirstValid() { Stream s = System.Web.HttpContext.Current.Request.InputStream; byte[] b = new byte[s.Length]; s.Read(b, 0, (int)s.Length); postStr = Encoding.UTF8.GetString(b); if (!string.IsNullOrEmpty(postStr)) { ResponseMsg(postStr); } } /// <summary> /// 返回信息結果(微信信息返回) /// </summary> /// <param name="weixinXML"></param> private void ResponseMsg(string weixinXML) { //回覆消息的部分:你的代碼寫在這裏 } /// <summary> /// 微信操做 /// </summary> private void WXOpera() { wxmessage wx = GetWxMessage(); string res = ""; if (!string.IsNullOrEmpty(wx.EventName) && wx.EventName.Trim() == "subscribe") { //剛關注時的時間,用於歡迎詞 string content = ""; content = "您好,歡迎關注XXX公衆號";
res = sendTextMessage(wx, content); HttpContext.Current.Response.Write(res); HttpContext.Current.Response.End(); } } /// <summary> /// 獲取和設置微信類中的信息 /// </summary> /// <returns></returns> private wxmessage GetWxMessage() { wxmessage wx = new wxmessage(); StreamReader str = new StreamReader(Request.InputStream, Encoding.UTF8); XmlDocument xml = new XmlDocument(); xml.Load(str); str.Close(); str.Dispose(); wx.ToUserName = xml.SelectSingleNode("xml").SelectSingleNode("ToUserName").InnerText; wx.FromUserName = xml.SelectSingleNode("xml").SelectSingleNode("FromUserName").InnerText; wx.MsgType = xml.SelectSingleNode("xml").SelectSingleNode("MsgType").InnerText; if (wx.MsgType.Trim() == "text") { wx.Content = xml.SelectSingleNode("xml").SelectSingleNode("Content").InnerText; } if (wx.MsgType.Trim() == "event") { wx.EventName = xml.SelectSingleNode("xml").SelectSingleNode("Event").InnerText; wx.EventKey = xml.SelectSingleNode("xml").SelectSingleNode("EventKey").InnerText; } return wx; } /// <summary> /// 發送文字消息 /// </summary> /// <param name="wx" />獲取的收發者信息 /// <param name="content" />內容 /// <returns></returns> private string sendTextMessage(wxmessage wx, string content) { string res = string.Format(Message_Text, wx.FromUserName, wx.ToUserName, DateTime.Now.Ticks, content); return res; } /// <summary> /// 普通文本消息 /// </summary> private static string Message_Text { get { return @"<xml> <ToUserName><![CDATA[{0}]]></ToUserName> <FromUserName><![CDATA[{1}]]></FromUserName> <CreateTime>{2}</CreateTime> <MsgType><![CDATA[text]]></MsgType> <Content><![CDATA[{3}]]></Content> </xml>"; } } }
其中:Message_Text屬性,是微信定義的發送文本消息格式,下面是微信官方給出的解釋:post
文本消息格式:測試
<xml> <ToUserName><![CDATA[toUser]]></ToUserName> <FromUserName><![CDATA[fromUser]]></FromUserName> <CreateTime>12345678</CreateTime> <MsgType><![CDATA[text]]></MsgType> <Content><![CDATA[你好]]></Content> </xml>
文本消息格式說明:
參數 | 是否必須 | 描述 |
---|---|---|
ToUserName | 是 | 接收方賬號(收到的OpenID) |
FromUserName | 是 | 開發者微信號 |
CreateTime | 是 | 消息建立時間 (整型) |
MsgType | 是 | text |
Content | 是 | 回覆的消息內容(換行:在content中可以換行,微信客戶端就支持換行顯示) |
注:有的朋友可能會將這裏的ToUserName和FromUserName,與接收事件的ToUserName和FromUserName混淆,可能你看出來了sendTextMessage()方法中參數順序與Message_Text屬性中的順序不一致。加密
而後從新將wxapi.aspx頁面發佈到服務器上面,隨後用本身的微信號關注測試公衆號(掃描測試公衆號的二維碼),關注完成以後,若是你能看到:您好,歡迎關注XXX公衆號 ,則說明自動回覆設置成功!spa