說起微信公眾帳號,大家都不會陌生,使用這個平臺能給網站或系統增加一個新亮點,直接進入正題吧,在使用之前一定要仔細閱讀官方API文檔。
使用.net實現的方法:
//微信接口地址 頁面代碼:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
weixin _wx = new weixin(); string postStr = "" ; if (Request.HttpMethod.ToLower() == "post" ) { 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)) //請求處理 { _wx.Handle(postStr); } } else { _wx.Auth(); } |
具體處理類
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
|
/// <summary> /// 微信公眾平臺操作類 /// </summary> public class weixin { private string Token = "my_weixin_token" ; //換成自己的token public void Auth() { string echoStr = System.Web.HttpContext.Current.Request.QueryString[ "echoStr" ]; if (CheckSignature()) //校驗簽名是否正確 { if (! string .IsNullOrEmpty(echoStr)) { System.Web.HttpContext.Current.Response.Write(echoStr); //返回原值表示校驗成功 System.Web.HttpContext.Current.Response.End(); } } } public void Handle( string postStr) { //封裝請求類 XmlDocument doc = new XmlDocument(); doc.LoadXml(postStr); XmlElement rootElement = doc.DocumentElement; //MsgType XmlNode MsgType = rootElement.SelectSingleNode( "MsgType" ); //接收的值--->接收消息類(也稱為消息推送) RequestXML requestXML = new RequestXML(); requestXML.ToUserName = rootElement.SelectSingleNode( "ToUserName" ).InnerText; requestXML.FromUserName = rootElement.SelectSingleNode( "FromUserName" ).InnerText; requestXML.CreateTime = rootElement.SelectSingleNode( "CreateTime" ).InnerText; requestXML.MsgType = MsgType.InnerText; //根據不同的類型進行不同的處理 switch (requestXML.MsgType) { case "text" : //文本消息 requestXML.Content = rootElement.SelectSingleNode( "Content" ).InnerText; break ; case "image" : //圖片 requestXML.PicUrl = rootElement.SelectSingleNode( "PicUrl" ).InnerText; break ; case "location" : //位置 requestXML.Location_X = rootElement.SelectSingleNode( "Location_X" ).InnerText; requestXML.Location_Y = rootElement.SelectSingleNode( "Location_Y" ).InnerText; requestXML.Scale = rootElement.SelectSingleNode( "Scale" ).InnerText; requestXML.Label = rootElement.SelectSingleNode( "Label" ).InnerText; break ; case "link" : //鏈接 break ; case "event" : //事件推送 支持V4.5+ break ; } //消息回復 ResponseMsg(requestXML); } /// <summary> /// 驗證微信簽名 /// * 將token、timestamp、nonce三個參數進行字典序排序 /// * 將三個參數字符串拼接成一個字符串進行sha1加密 /// * 開發者獲得加密后的字符串可與signature對比,標識該請求來源于微信。 /// </summary> /// <returns></returns> private bool CheckSignature() { string signature = System.Web.HttpContext.Current.Request.QueryString[ "signature" ]; string timestamp = System.Web.HttpContext.Current.Request.QueryString[ "timestamp" ]; string nonce = System.Web.HttpContext.Current.Request.QueryString[ "nonce" ]; //加密/校驗流程: //1. 將token、timestamp、nonce三個參數進行字典序排序 string [] ArrTmp = { Token, timestamp, nonce }; Array.Sort(ArrTmp); //字典排序 //2.將三個參數字符串拼接成一個字符串進行sha1加密 string tmpStr = string .Join( "" , ArrTmp); tmpStr = FormsAuthentication.HashPasswordForStoringInConfigFile(tmpStr, "SHA1" ); tmpStr = tmpStr.ToLower(); //3.開發者獲得加密后的字符串可與signature對比,標識該請求來源于微信。 if (tmpStr == signature) { return true ; } else { return false ; } } /// <summary> /// 消息回復(微信信息返回) /// </summary> /// <param name="requestXML">The request XML.</param> private void ResponseMsg(RequestXML requestXML) { try { string resxml = "" ; //主要是調用數據庫進行關鍵詞匹配自動回復內容,可以根據自己的業務情況編寫。 //1.通常有,沒有匹配任何指令時,返回幫助信息 AutoResponse mi = new AutoResponse(requestXML.Content, requestXML.FromUserName); switch (requestXML.MsgType) { case "text" : //在這里執行一系列操作,從而實現自動回復內容. string _reMsg = mi.GetReMsg(); if (mi.msgType == 1) { 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>" ; resxml += mi.GetRePic(requestXML.FromUserName); resxml += "</Articles><FuncFlag>1</FuncFlag></xml>" ; } else { 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>" ; } break ; case "location" : string city = GetMapInfo(requestXML.Location_X, requestXML.Location_Y); if (city == "0" ) { 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>" ; } else { 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>" ; } break ; case "image" : //圖文混合的消息 具體格式請見官方API“回復圖文消息” break ; } System.Web.HttpContext.Current.Response.Write(resxml); WriteToDB(requestXML, resxml, mi.pid); } catch (Exception ex) { //WriteTxt("異常:" + ex.Message + "Struck:" + ex.StackTrace.ToString()); //wx_logs.MyInsert("異常:" + ex.Message + "Struck:" + ex.StackTrace.ToString()); } } /// <summary> /// unix時間轉換為datetime /// </summary> /// <param name="timeStamp"></param> /// <returns></returns> private DateTime UnixTimeToTime( string timeStamp) { DateTime dtStart = TimeZone.CurrentTimeZone.ToLocalTime( new DateTime(1970, 1, 1)); long lTime = long .Parse(timeStamp + "0000000" ); TimeSpan toNow = new TimeSpan(lTime); return dtStart.Add(toNow); } /// <summary> /// datetime轉換為unixtime /// </summary> /// <param name="time"></param> /// <returns></returns> private int ConvertDateTimeInt(System.DateTime time) { System.DateTime startTime = TimeZone.CurrentTimeZone.ToLocalTime( new System.DateTime(1970, 1, 1)); return ( int )(time - startTime).TotalSeconds; } /// <summary> /// 調用百度地圖,返回坐標信息 /// </summary> /// <param name="y">經度</param> /// <param name="x">緯度</param> /// <returns></returns> public string GetMapInfo( string x, string y) { try { string res = string .Empty; string parame = string .Empty; string url = "http://maps.googleapis.com/maps/api/geocode/xml" ; parame = "latlng=" + x + "," + y + "&language=zh-CN&sensor=false" ; //此key為個人申請 res = webRequestPost(url, parame); XmlDocument doc = new XmlDocument(); doc.LoadXml(res); XmlElement rootElement = doc.DocumentElement; string Status = rootElement.SelectSingleNode( "status" ).InnerText; if (Status == "OK" ) { //僅獲取城市 XmlNodeList xmlResults = rootElement.SelectSingleNode( "/GeocodeResponse" ).ChildNodes; for ( int i = 0; i < xmlResults.Count; i++) { XmlNode childNode = xmlResults[i]; if (childNode.Name == "status" ) { continue ; } string city = "0" ; for ( int w = 0; w < childNode.ChildNodes.Count; w++) { for ( int q = 0; q < childNode.ChildNodes[w].ChildNodes.Count; q++) { XmlNode childeTwo = childNode.ChildNodes[w].ChildNodes[q]; if (childeTwo.Name == "long_name" ) { city = childeTwo.InnerText; } else if (childeTwo.InnerText == "locality" ) { return city; } } } return city; } } } catch (Exception ex) { //WriteTxt("map異常:" + ex.Message.ToString() + "Struck:" + ex.StackTrace.ToString()); return "0" ; } return "0" ; } /// <summary> /// Post 提交調用抓取 /// </summary> /// <param name="url">提交地址</param> /// <param name="param">參數</param> /// <returns>string</returns> public string webRequestPost( string url, string param) { byte [] bs = System.Text.Encoding.UTF8.GetBytes(param); HttpWebRequest req = (HttpWebRequest)HttpWebRequest.Create(url + "?" + param); req.Method = "Post" ; req.Timeout = 120 * 1000; req.ContentType = "application/x-www-form-urlencoded;" ; req.ContentLength = bs.Length; using (Stream reqStream = req.GetRequestStream()) { reqStream.Write(bs, 0, bs.Length); reqStream.Flush(); } using (WebResponse wr = req.GetResponse()) { //在這里對接收到的頁面內容進行處理 Stream strm = wr.GetResponseStream(); StreamReader sr = new StreamReader(strm, System.Text.Encoding.UTF8); string line; System.Text.StringBuilder sb = new System.Text.StringBuilder(); while ((line = sr.ReadLine()) != null ) { sb.Append(line + System.Environment.NewLine); } sr.Close(); strm.Close(); return sb.ToString(); } } /// <summary> /// 將本次交互信息保存至數據庫中 /// </summary> /// <param name="requestXML"></param> /// <param name="_xml"></param> /// <param name="_pid"></param> private void WriteToDB(RequestXML requestXML, string _xml, int _pid) { WeiXinMsg wx = new WeiXinMsg(); wx.FromUserName = requestXML.FromUserName; wx.ToUserName = requestXML.ToUserName; wx.MsgType = requestXML.MsgType; wx.Msg = requestXML.Content; wx.Creatime = requestXML.CreateTime; wx.Location_X = requestXML.Location_X; wx.Location_Y = requestXML.Location_Y; wx.Label = requestXML.Label; wx.Scale = requestXML.Scale; wx.PicUrl = requestXML.PicUrl; wx.reply = _xml; wx.pid = _pid; try { wx.Add(); } catch (Exception ex) { //wx_logs.MyInsert(ex.Message); //ex.message; } } } |
響應類MODEL
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
|
#region 微信請求類 RequestXML /// <summary> /// 微信請求類 /// </summary> public class RequestXML { private string toUserName = "" ; /// <summary> /// 消息接收方微信號,一般為公眾平臺賬號微信號 /// </summary> public string ToUserName { get { return toUserName; } set { toUserName = value; } } private string fromUserName = "" ; /// <summary> /// 消息發送方微信號 /// </summary> public string FromUserName { get { return fromUserName; } set { fromUserName = value; } } private string createTime = "" ; /// <summary> /// 創建時間 /// </summary> public string CreateTime { get { return createTime; } set { createTime = value; } } private string msgType = "" ; /// <summary> /// 信息類型 地理位置:location,文本消息:text,消息類型:image /// </summary> public string MsgType { get { return msgType; } set { msgType = value; } } private string content = "" ; /// <summary> /// 信息內容 /// </summary> public string Content { get { return content; } set { content = value; } } private string location_X = "" ; /// <summary> /// 地理位置緯度 /// </summary> public string Location_X { get { return location_X; } set { location_X = value; } } private string location_Y = "" ; /// <summary> /// 地理位置經度 /// </summary> public string Location_Y { get { return location_Y; } set { location_Y = value; } } private string scale = "" ; /// <summary> /// 地圖縮放大小 /// </summary> public string Scale { get { return scale; } set { scale = value; } } private string label = "" ; /// <summary> /// 地理位置信息 /// </summary> public string Label { get { return label; } set { label = value; } } private string picUrl = "" ; /// <summary> /// 圖片鏈接,開發者可以用HTTP GET獲取 /// </summary> public string PicUrl { get { return picUrl; } set { picUrl = value; } } } #endregion |
通過閱讀這篇文章,大家就大概知道.net如何實現微信公眾賬號接口開發的,希望這篇文章對大家的學習有所幫助。