时间:2021-07-01 10:21:17 帮助过:25人阅读
一.前言
微信公众平台的消息处理还是比较完善的,有最基本的文本消息,到图文消息,到图片消息,语音消息,视频消息,音乐消息其基本原理都是一样的,只不过所post的xml数据有所差别,在处理消息之前,我们要认真阅读,官方给我们的文档:http://mp.weixin.qq.com/wiki/14/89b871b5466b19b3efa4ada8e577d45e.html。首先我们从最基本的文本消息处理开始。
- <xml>
- <ToUserName><![CDATA[toUser]]></ToUserName>
- <FromUserName><![CDATA[fromUser]]></FromUserName>
- <CreateTime>12345678</CreateTime>
- <MsgType><![CDATA[text]]></MsgType>
- <Content><![CDATA[你好]]></Content>
- </xml>
我们可以看到这是消息处理的一个最基本的模式,有发送者,接受者,创建时间,类型,内容等等。
首先我们来创建一个消息处理的类,这个类用来捕获,所有的消息请求,根据不同的消息请求类型来处理不同的消息回复。
- 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的代码如下
- 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类中的消息相应至关重要。
- /// <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处理类实现这个接口。代码如下
- /// <summary>
- /// 处理接口
- /// </summary>
- public interface IHandler
- {
- /// <summary>
- /// 处理请求
- /// </summary>
- /// <returns></returns>
- string HandleRequest();
- }
EventHandler
- 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
- /// <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
- /// <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
- 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> ";
- }
- }
最后我们的效果如下所示;
以上所述就是本文的全部内容了,希望大家能够喜欢