一.前言
微信公众平台的消息处理还是比较完善的,有最基本的文本消息,到图文消息,到图片消息,语音消息,视频消息,音乐消息其基本原理都是一样的,只不过所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> " ;
}
}
|
最后我们的效果如下所示;
以上所述就是本文的全部内容了,希望大家能够喜欢