1 using System;
2 using System.Collections;
3 using System.Configuration;
4 using System.Data;
5 using System.Linq;
6 using System.Web;
7 using System.Web.Security;
8 using System.Web.UI;
9 using System.Web.UI.HtmlControls;
10 using System.Web.UI.WebControls;
11 using System.Web.UI.WebControls.WebParts;
12 using System.Xml.Linq;
13 using System.Xml;
14 using System.IO;
15 using System.Text;
16 using System.Collections.Generic;
17 using System.Net;
18
19
20 namespace weixin
21 {
22 public partial class index : System.Web.UI.Page
23 {
24 const string Token = "token"; //与那边填写的token一致
25 protected void Page_Load(object sender, EventArgs e)
26 {
27 string postStr = "";
28 if (Request.HttpMethod.ToLower() == "post")
29 {
30 Stream s = System.Web.HttpContext.Current.Request.InputStream;
31 byte[] b = new byte[s.Length];
32 s.Read(b, 0, (int)s.Length);
33 postStr = Encoding.UTF8.GetString(b);
34
35
36 if (!string.IsNullOrEmpty(postStr))
37 {
38 //封装请求类
39 XmlDocument doc = new XmlDocument();
40 doc.LoadXml(postStr);
41 XmlElement rootElement = doc.DocumentElement;
42
43
44 XmlNode MsgType = rootElement.SelectSingleNode("MsgType");
45
46
47 RequestXML requestXML = new RequestXML();
48 requestXML.ToUserName = rootElement.SelectSingleNode("ToUserName").InnerText;
49 requestXML.FromUserName = rootElement.SelectSingleNode("FromUserName").InnerText;
50 requestXML.CreateTime = rootElement.SelectSingleNode("CreateTime").InnerText;
51 requestXML.MsgType = MsgType.InnerText;
52
53
54 if (requestXML.MsgType == "text")
55 {
56 requestXML.Content = rootElement.SelectSingleNode("Content").InnerText;
57 }
58 else if (requestXML.MsgType == "location")
59 {
60 requestXML.Location_X = rootElement.SelectSingleNode("Location_X").InnerText;
61 requestXML.Location_Y = rootElement.SelectSingleNode("Location_Y").InnerText;
62 requestXML.Scale = rootElement.SelectSingleNode("Scale").InnerText;
63 requestXML.Label = rootElement.SelectSingleNode("Label").InnerText;
64 }
65 else if (requestXML.MsgType == "image")
66 {
67 requestXML.PicUrl = rootElement.SelectSingleNode("PicUrl").InnerText;
68 }
69
70
71 //回复消息
72 ResponseMsg(requestXML);
73 }
74 }
75 else
76 {
77 Valid();
78 }
79 }
80
81
82 /// <summary>
83 /// 验证微信签名
84 /// </summary>
85 /// * 将token、timestamp、nonce三个参数进行字典序排序
86 /// * 将三个参数字符串拼接成一个字符串进行sha1加密
87 /// * 开发者获得加密后的字符串可与signature对比,标识该请求来源于微信。
88 /// <returns></returns>
89 private bool CheckSignature()
90 {
91 string signature = Request.QueryString["signature"];
92 string timestamp = Request.QueryString["timestamp"];
93 string nonce = Request.QueryString["nonce"];
94 string[] ArrTmp = { Token, timestamp, nonce };
95 Array.Sort(ArrTmp); //字典排序
96 string tmpStr = string.Join("", ArrTmp);
97 tmpStr = FormsAuthentication.HashPasswordForStoringInConfigFile(tmpStr, "SHA1");
98 tmpStr = tmpStr.ToLower();
99 if (tmpStr == signature)
100 {
101 return true;
102 }
103 else
104 {
105 return false;
106 }
107 }
108
109
110 private void Valid()
111 {
112 string echoStr = Request.QueryString["echoStr"];
113 if (CheckSignature())
114 {
115 if (!string.IsNullOrEmpty(echoStr))
116 {
117 Response.Write(echoStr);
118 Response.End();
119 }
120 }
121 }
122
123
124 /// <summary>
125 /// 回复消息(微信信息返回)
126 /// </summary>
127 /// <param name="weixinXML"></param>
128 private void ResponseMsg(RequestXML requestXML)
129 {
130 try
131 {
132 string resxml = "";
133 if (requestXML.MsgType == "text")
134 {
135 resxml = "<xml><ToUserName><![CDATA[" + requestXML.FromUserName + "]]></ToUserName><FromUserName><![CDATA[" + requestXML.ToUserName + "]]></FromUserName><CreateTime>" + ConvertDateTimeInt(DateTime.Now) + "</CreateTime><MsgType><![CDATA[text]]></MsgType><Content><![CDATA[正在建设中,稍等时日,更多精彩……]]></Content><FuncFlag>0</FuncFlag></xml>";
136 }
137 else if (requestXML.MsgType == "location")
138 {
139 string city = GetMapInfo(requestXML.Location_X, requestXML.Location_Y);
140 if (city == "0")
141 {
142 resxml = "<xml><ToUserName><![CDATA[" + requestXML.FromUserName + "]]></ToUserName><FromUserName><![CDATA[" + requestXML.ToUserName + "]]></FromUserName><CreateTime>" + ConvertDateTimeInt(DateTime.Now) + "</CreateTime><MsgType><![CDATA[text]]></MsgType><Content><![CDATA[Sorry,没有找到" + city + " 的相关产品信息]]></Content><FuncFlag>0</FuncFlag></xml>";
143 }
144 else
145 {
146 resxml = "<xml><ToUserName><![CDATA[" + requestXML.FromUserName + "]]></ToUserName><FromUserName><![CDATA[" + requestXML.ToUserName + "]]></FromUserName><CreateTime>" + ConvertDateTimeInt(DateTime.Now) + "</CreateTime><MsgType><![CDATA[text]]></MsgType><Content><![CDATA[Sorry,这是 " + city + " 的产品信息:圈圈叉叉]]></Content><FuncFlag>0</FuncFlag></xml>";
147 }
148 }
149 else if (requestXML.MsgType == "image")
150 {
151 //返回10以内条
152 int size = 10;
153 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>" + size + "</ArticleCount><Articles>";
154 List<string> list = new List<string>();
155 //假如有20条查询的返回结果
156 for (int i = 0; i < 20; i++)
157 {
158 list.Add("1");
159 }
160 string[] piclist = new string[] { "/Abstract_Pencil_Scribble_Background_Vector_main.jpg", "/balloon_tree.jpg", "/bloom.jpg", "/colorful_flowers.jpg", "/colorful_summer_flower.jpg", "/fall.jpg", "/fall_tree.jpg", "/growing_flowers.jpg", "/shoes_illustration.jpg", "/splashed_tree.jpg" };
161
162
163 for (int i = 0; i < size && i < list.Count; i++)
164 {
165 resxml += "<item><Title><![CDATA[沈阳-黑龙江]]></Title><Description><![CDATA[元旦特价:¥300 市场价:¥400]]></Description><PicUrl><![CDATA[" + "http://www.hougelou.com" + piclist[i] + "]]></PicUrl><Url><![CDATA[http://www.hougelou.com]]></Url></item>";
166 }
167 resxml += "</Articles><FuncFlag>1</FuncFlag></xml>";
168 }
169 WriteTxt(resxml);
170 Response.Write(resxml);
171 }
172 catch (Exception ex)
173 {
174 WriteTxt("异常:" + ex.Message + "Struck:" + ex.StackTrace.ToString());
175 }
176 }
177
178
179
180
181
182
183 /// <summary>
184 /// unix时间转换为datetime
185 /// </summary>
186 /// <param name="timeStamp"></param>
187 /// <returns></returns>
188 private DateTime UnixTimeToTime(string timeStamp)
189 {
190 DateTime dtStart = TimeZone.CurrentTimeZone.ToLocalTime(new DateTime(1970, 1, 1));
191 long lTime = long.Parse(timeStamp + "0000000");
192 TimeSpan toNow = new TimeSpan(lTime);
193 return dtStart.Add(toNow);
194 }
195
196
197 /// <summary>
198 /// datetime转换为unixtime
199 /// </summary>
200 /// <param name="time"></param>
201 /// <returns></returns>
202 private int ConvertDateTimeInt(System.DateTime time)
203 {
204 System.DateTime startTime = TimeZone.CurrentTimeZone.ToLocalTime(new System.DateTime(1970, 1, 1));
205 return (int)(time - startTime).TotalSeconds;
206 }
207
208
209 /// <summary>
210 /// 记录bug,以便调试
211 /// </summary>
212 /// <returns></returns>
213 public bool WriteTxt(string str)
214 {
215 try
216 {
217 FileStream fs = new FileStream(Server.MapPath("/bugLog.txt"), FileMode.Append);
218 StreamWriter sw = new StreamWriter(fs);
219 //开始写入
220 sw.WriteLine(str);
221 //清空缓冲区
222 sw.Flush();
223 //关闭流
224 sw.Close();
225 fs.Close();
226 }
227 catch (Exception)
228 {
229 return false;
230 }
231 return true;
232 }
233
234
235 /// <summary>
236 /// 调用百度地图,返回坐标信息
237 /// </summary>
238 /// <param name="y">经度</param>
239 /// <param name="x">纬度</param>
240 /// <returns></returns>
241 public string GetMapInfo(string x, string y)
242 {
243 try
244 {
245 string res = string.Empty;
246 string parame = string.Empty;
247 string url = "http://maps.googleapis.com/maps/api/geocode/xml";
248 parame = "latlng=" + x + "," + y + "&language=zh-CN&sensor=false";//此key为个人申请
249 res = webRequestPost(url, parame);
250
251
252 XmlDocument doc = new XmlDocument();
253
254
255 doc.LoadXml(res);
256 XmlElement rootElement = doc.DocumentElement;
257 string Status = rootElement.SelectSingleNode("status").InnerText;
258 if (Status == "OK")
259 {
260 //仅获取城市
261 XmlNodeList xmlResults = rootElement.SelectSingleNode("/GeocodeResponse").ChildNodes;
262 for (int i = 0; i < xmlResults.Count; i++)
263 {
264 XmlNode childNode = xmlResults[i];
265 if (childNode.Name == "status")
266 {
267 continue;
268 }
269
270
271 string city = "0";
272 for (int w = 0; w < childNode.ChildNodes.Count; w++)
273 {
274 for (int q = 0; q < childNode.ChildNodes[w].ChildNodes.Count; q++)
275 {
276 XmlNode childeTwo = childNode.ChildNodes[w].ChildNodes[q];
277
278
279 if (childeTwo.Name == "long_name")
280 {
281 city = childeTwo.InnerText;
282 }
283 else if (childeTwo.InnerText == "locality")
284 {
285 return city;
286 }
287 }
288 }
289 return city;
290 }
291 }
292 }
293 catch (Exception ex)
294 {
295 WriteTxt("map异常:" + ex.Message.ToString() + "Struck:" + ex.StackTrace.ToString());
296 return "0";
297 }
298
299
300 return "0";
301 }
302
303
304 /// <summary>
305 /// Post 提交调用抓取
306 /// </summary>
307 /// <param name="url">提交地址</param>
308 /// <param name="param">参数</param>
309 /// <returns>string</returns>
310 public string webRequestPost(string url, string param)
311 {
312 byte[] bs = System.Text.Encoding.UTF8.GetBytes(param);
313
314
315 HttpWebRequest req = (HttpWebRequest)HttpWebRequest.Create(url + "?" + param);
316 req.Method = "Post";
317 req.Timeout = 120 * 1000;
318 req.ContentType = "application/x-www-form-urlencoded;";
319 req.ContentLength = bs.Length;
320
321
322 using (Stream reqStream = req.GetRequestStream())
323 {
324 reqStream.Write(bs, 0, bs.Length);
325 reqStream.Flush();
326 }
327 using (WebResponse wr = req.GetResponse())
328 {
329 //在这里对接收到的页面内容进行处理
330
331
332 Stream strm = wr.GetResponseStream();
333
334
335 StreamReader sr = new StreamReader(strm, System.Text.Encoding.UTF8);
336
337
338 string line;
339
340
341 System.Text.StringBuilder sb = new System.Text.StringBuilder();
342
343
344 while ((line = sr.ReadLine()) != null)
345 {
346 sb.Append(line + System.Environment.NewLine);
347 }
348 sr.Close();
349 strm.Close();
350 return sb.ToString();
351 }
352 }
353
354
355
356
357 }
358
359
360 //微信请求类
361 public class RequestXML
362 {
363 private string toUserName;
364 /// <summary>
365 /// 消息接收方微信号,一般为公众平台账号微信号
366 /// </summary>
367 public string ToUserName
368 {
369 get { return toUserName; }
370 set { toUserName = value; }
371 }
372
373
374 private string fromUserName;
375 /// <summary>
376 /// 消息发送方微信号
377 /// </summary>
378 public string FromUserName
379 {
380 get { return fromUserName; }
381 set { fromUserName = value; }
382 }
383
384
385 private string createTime;
386 /// <summary>
387 /// 创建时间
388 /// </summary>
389 public string CreateTime
390 {
391 get { return createTime; }
392 set { createTime = value; }
393 }
394
395
396 private string msgType;
397 /// <summary>
398 /// 信息类型 地理位置:location,文本消息:text,消息类型:image
399 /// </summary>
400 public string MsgType
401 {
402 get { return msgType; }
403 set { msgType = value; }
404 }
405
406
407 private string content;
408 /// <summary>
409 /// 信息内容
410 /// </summary>
411 public string Content
412 {
413 get { return content; }
414 set { content = value; }
415 }
416
417
418 private string location_X;
419 /// <summary>
420 /// 地理位置纬度
421 /// </summary>
422 public string Location_X
423 {
424 get { return location_X; }
425 set { location_X = value; }
426 }
427
428
429 private string location_Y;
430 /// <summary>
431 /// 地理位置经度
432 /// </summary>
433 public string Location_Y
434 {
435 get { return location_Y; }
436 set { location_Y = value; }
437 }
438
439
440 private string scale;
441 /// <summary>
442 /// 地图缩放大小
443 /// </summary>
444 public string Scale
445 {
446 get { return scale; }
447 set { scale = value; }
448 }
449
450
451 private string label;
452 /// <summary>
453 /// 地理位置信息
454 /// </summary>
455 public string Label
456 {
457 get { return label; }
458 set { label = value; }
459 }
460
461
462 private string picUrl;
463 /// <summary>
464 /// 图片链接,开发者可以用HTTP GET获取
465 /// </summary>
466 public string PicUrl
467 {
468 get { return picUrl; }
469 set { picUrl = value; }
470 }
471 }
472 }