一.前言
微信公众平台的消息处理还是比较完善的,有最基本的文本消息,到图文消息,到图片消息,语音消息,视频消息,音乐消息其基本原理都是一样的,只不过所post的xml数据有所差别,在处理消息之前,我们要认真阅读,官方给我们的文档:http://mp.weixin.qq.com/wiki/14/89b871b5466b19b3efa4ada8e577d45e.html。首先我们从最基本的文本消息处理开始。
1
2
3
4
5
6
7
|
< xml > < ToUserName > <![CDATA[toUser]]> </ ToUserName > < FromUserName > <![CDATA[fromUser]]> </ FromUserName > < CreateTime >12345678</ CreateTime > < MsgType > <![CDATA[text]]> </ MsgType > < Content > <![CDATA[你好]]> </ Content > </ xml > |
我们可以看到这是消息处理的一个最基本的模式,有发送者,接受者,创建时间,类型,内容等等。
首先我们来创建一个消息处理的类,这个类用来捕获,所有的消息请求,根据不同的消息请求类型来处理不同的消息回复。
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
|
public class WeiXinService { /// <summary> /// TOKEN /// </summary> private const string TOKEN = "finder" ; /// <summary> /// 签名 /// </summary> private const string SIGNATURE = "signature" ; /// <summary> /// 时间戳 /// </summary> private const string TIMESTAMP = "timestamp" ; /// <summary> /// 随机数 /// </summary> private const string NONCE = "nonce" ; /// <summary> /// 随机字符串 /// </summary> private const string ECHOSTR = "echostr" ; /// <summary> /// /// </summary> private HttpRequest Request { get ; set ; } /// <summary> /// 构造函数 /// </summary> /// <param name="request"></param> public WeiXinService(HttpRequest request) { this .Request = request; } /// <summary> /// 处理请求,产生响应 /// </summary> /// <returns></returns> public string Response() { string method = Request.HttpMethod.ToUpper(); //验证签名 if (method == "GET" ) { if (CheckSignature()) { return Request.QueryString[ECHOSTR]; } else { return "error" ; } } //处理消息 if (method == "POST" ) { return ResponseMsg(); } else { return "无法处理" ; } } /// <summary> /// 处理请求 /// </summary> /// <returns></returns> private string ResponseMsg() { string requestXml = CommonWeiXin.ReadRequest( this .Request); IHandler handler = HandlerFactory.CreateHandler(requestXml); if (handler != null ) { return handler.HandleRequest(); } return string .Empty; } /// <summary> /// 检查签名 /// </summary> /// <param name="request"></param> /// <returns></returns> private bool CheckSignature() { string signature = Request.QueryString[SIGNATURE]; string timestamp = Request.QueryString[TIMESTAMP]; string nonce = Request.QueryString[NONCE]; List< string > list = new List< string >(); list.Add(TOKEN); list.Add(timestamp); list.Add(nonce); //排序 list.Sort(); //拼串 string input = string .Empty; foreach (var item in list) { input += item; } //加密 string new_signature = SecurityUtility.SHA1Encrypt(input); //验证 if (new_signature == signature) { return true ; } else { return false ; } } } |
在来看看我们的首先是如何捕获消息的。首页Default.ashx的代码如下
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
|
public void ProcessRequest(HttpContext context) { context.Response.ContentType = "text/html" ; string postString = string .Empty; if (HttpContext.Current.Request.HttpMethod.ToUpper() == "POST" ) { //由微信服务接收请求,具体处理请求 WeiXinService wxService = new WeiXinService(context.Request); string responseMsg = wxService.Response(); context.Response.Clear(); context.Response.Charset = "UTF-8" ; context.Response.Write(responseMsg); context.Response.End(); } else { string token = "wei2414201" ; if ( string .IsNullOrEmpty(token)) { return ; } string echoString = HttpContext.Current.Request.QueryString[ "echoStr" ]; string signature = HttpContext.Current.Request.QueryString[ "signature" ]; string timestamp = HttpContext.Current.Request.QueryString[ "timestamp" ]; string nonce = HttpContext.Current.Request.QueryString[ "nonce" ]; if (! string .IsNullOrEmpty(echoString)) { HttpContext.Current.Response.Write(echoString); HttpContext.Current.Response.End(); } } } |
从上面的代码中我们可以看到WeiXinService.cs类中的消息相应至关重要。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
/// <summary> /// 处理请求 /// </summary> /// <returns></returns> private string ResponseMsg() { string requestXml = CommonWeiXin.ReadRequest( this .Request); IHandler handler = HandlerFactory.CreateHandler(requestXml); if (handler != null ) { return handler.HandleRequest(); } return string .Empty; } |
IHandler是一个消息处理接口,其下面有EventHandler,TextHandler处理类实现这个接口。代码如下
1
2
3
4
5
6
7
8
9
10
11
|
/// <summary> /// 处理接口 /// </summary> public interface IHandler { /// <summary> /// 处理请求 /// </summary> /// <returns></returns> string HandleRequest(); } |
EventHandler
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
|
class EventHandler : IHandler { /// <summary> /// 请求的xml /// </summary> private string RequestXml { get ; set ; } /// <summary> /// 构造函数 /// </summary> /// <param name="requestXml"></param> public EventHandler( string requestXml) { this .RequestXml = requestXml; } /// <summary> /// 处理请求 /// </summary> /// <returns></returns> public string HandleRequest() { string response = string .Empty; EventMessage em = EventMessage.LoadFromXml(RequestXml); if (em.Event.Equals( "subscribe" , StringComparison.OrdinalIgnoreCase)) //用来判断是不是首次关注 { PicTextMessage tm = new PicTextMessage(); //我自己创建的一个图文消息处理类 tm.ToUserName = em.FromUserName; tm.FromUserName = em.ToUserName; tm.CreateTime = CommonWeiXin.GetNowTime(); response = tm.GenerateContent(); } return response; } } |
TextHandler
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
|
/// <summary> /// 文本信息处理类 /// </summary> public class TextHandler : IHandler { string openid { get ; set ; } string access_token { get ; set ; } /// <summary> /// 请求的XML /// </summary> private string RequestXml { get ; set ; } /// <summary> /// 构造函数 /// </summary> /// <param name="requestXml">请求的xml</param> public TextHandler( string requestXml) { this .RequestXml = requestXml; } /// <summary> /// 处理请求 /// </summary> /// <returns></returns> public string HandleRequest() { string response = string .Empty; TextMessage tm = TextMessage.LoadFromXml(RequestXml); string content = tm.Content.Trim(); if ( string .IsNullOrEmpty(content)) { response = "您什么都没输入,没法帮您啊。" ; } else { string username = System.Configuration.ConfigurationManager.AppSettings[ "weixinid" ].ToString(); AccessToken token = AccessToken.Get(username); access_token = token.access_token; openid = tm.FromUserName; response = HandleOther(content); } tm.Content = response; //进行发送者、接收者转换 string temp = tm.ToUserName; tm.ToUserName = tm.FromUserName; tm.FromUserName = temp; response = tm.GenerateContent(); return response; } /// <summary> /// 处理其他消息 /// </summary> /// <param name="tm"></param> /// <returns></returns> private string HandleOther( string requestContent) { string response = string .Empty; if (requestContent.Contains( "你好" ) || requestContent.Contains( "您好" )) { response = "您也好~" ; } else if (requestContent.Contains( "openid" ) || requestContent.Contains( "id" ) || requestContent.Contains( "ID" )) //用来匹配用户输入的关键字 { response = "你的Openid: " +openid; } else if (requestContent.Contains( "token" ) || requestContent.Contains( "access_token" )) { response = "你的access_token: " + access_token; } else { response = "试试其他关键字吧。" ; } return response; } } |
HandlerFactory
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
|
/// <summary> /// 处理器工厂类 /// </summary> public class HandlerFactory { /// <summary> /// 创建处理器 /// </summary> /// <param name="requestXml">请求的xml</param> /// <returns>IHandler对象</returns> public static IHandler CreateHandler( string requestXml) { IHandler handler = null ; if (! string .IsNullOrEmpty(requestXml)) { //解析数据 XmlDocument doc = new System.Xml.XmlDocument(); doc.LoadXml(requestXml); XmlNode node = doc.SelectSingleNode( "/xml/MsgType" ); if (node != null ) { XmlCDataSection section = node.FirstChild as XmlCDataSection; if (section != null ) { string msgType = section.Value; switch (msgType) { case "text" : handler = new TextHandler(requestXml); break ; case "event" : handler = new EventHandler(requestXml); break ; } } } } return handler; } } |
在这里基本的一些类已经完成了,现在我们来完成,关注我们的微信公众号,我们就发送一条图文消息,同时输入我们的一些关键字,返回一些消息,比如输入id返回用户的openid等等。
二.PicTextMessage
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
|
public class PicTextMessage : Message { /// <summary> /// 模板静态字段 /// </summary> private static string m_Template; /// <summary> /// 默认构造函数 /// </summary> public PicTextMessage() { this .MsgType = "news" ; } /// <summary> /// 从xml数据加载文本消息 /// </summary> /// <param name="xml"></param> public static PicTextMessage LoadFromXml( string xml) { PicTextMessage tm = null ; if (! string .IsNullOrEmpty(xml)) { XElement element = XElement.Parse(xml); if (element != null ) { tm = new PicTextMessage(); tm.FromUserName = element.Element(CommonWeiXin.FROM_USERNAME).Value; tm.ToUserName = element.Element(CommonWeiXin.TO_USERNAME).Value; tm.CreateTime = element.Element(CommonWeiXin.CREATE_TIME).Value; } } return tm; } /// <summary> /// 模板 /// </summary> public override string Template { get { if ( string .IsNullOrEmpty(m_Template)) { LoadTemplate(); } return m_Template; } } /// <summary> /// 生成内容 /// </summary> /// <returns></returns> public override string GenerateContent() { this .CreateTime = CommonWeiXin.GetNowTime(); string str= string .Format( this .Template, this .ToUserName, this .FromUserName, this .CreateTime); return str; } /// <summary> /// 加载模板 /// </summary> private static void LoadTemplate() { m_Template= @"<xml> <ToUserName><![CDATA[{0}]]></ToUserName> <FromUserName><![CDATA[{1}]]></FromUserName> <CreateTime>{2}</CreateTime> <MsgType><![CDATA[news]]></MsgType> <ArticleCount>1</ArticleCount> <Articles> <item> <Title><![CDATA[有位停车欢迎你!]]></Title> <Description><![CDATA[如有问题请致电400-6238-136或直接在微信留言,我们将第一时间为您服务!]]></Description> <PicUrl><![CDATA[http://www.baidu.com/youwei.jpg]]></PicUrl> <Url><![CDATA[http://www.baidu.com]]></Url> </item> </Articles> </xml> " ; } } |
最后我们的效果如下所示;
以上所述就是本文的全部内容了,希望大家能够喜欢