详解.NET开发微信公众号之公众号消息处理方法
本文给大家讲述的是在.net微信公众号开发中的公众号的消息处理的相关内容,非常详细,有需要的小伙伴可以参考下。
一.前言
微信公众平台的消息处理还是比较完善的,有最基本的文本消息,到图文消息,到图片消息,语音消息,视频消息,音乐消息其基本原理都是一样的,只不过所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();}EventHandlerclass 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等等。
二.PicTextMessagepublic 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.php.cn/]]></PicUrl><Url><![CDATA[http://www.php.cn/]]></Url></item></Articles></xml> ";}}最后我们的效果如下所示;
以上所述就是本文的全部内容了,希望大家能够喜欢以上就是详解.NET开发微信公众号之公众号消息处理方法的详细内容,更多请关注小潘博客其它相关文章!