当前位置:Gxlcms > asp.net > .NET微信公众号开发之公众号消息处理

.NET微信公众号开发之公众号消息处理

时间:2021-07-01 10:21:17 帮助过:25人阅读

一.前言

  微信公众平台的消息处理还是比较完善的,有最基本的文本消息,到图文消息,到图片消息,语音消息,视频消息,音乐消息其基本原理都是一样的,只不过所post的xml数据有所差别,在处理消息之前,我们要认真阅读,官方给我们的文档:http://mp.weixin.qq.com/wiki/14/89b871b5466b19b3efa4ada8e577d45e.html。首先我们从最基本的文本消息处理开始。

  1. <xml>
  2. <ToUserName><![CDATA[toUser]]></ToUserName>
  3. <FromUserName><![CDATA[fromUser]]></FromUserName>
  4. <CreateTime>12345678</CreateTime>
  5. <MsgType><![CDATA[text]]></MsgType>
  6. <Content><![CDATA[你好]]></Content>
  7. </xml>

  我们可以看到这是消息处理的一个最基本的模式,有发送者,接受者,创建时间,类型,内容等等。

首先我们来创建一个消息处理的类,这个类用来捕获,所有的消息请求,根据不同的消息请求类型来处理不同的消息回复。

  1. public class WeiXinService
  2. {
  3. /// <summary>
  4. /// TOKEN
  5. /// </summary>
  6. private const string TOKEN = "finder";
  7. /// <summary>
  8. /// 签名
  9. /// </summary>
  10. private const string SIGNATURE = "signature";
  11. /// <summary>
  12. /// 时间戳
  13. /// </summary>
  14. private const string TIMESTAMP = "timestamp";
  15. /// <summary>
  16. /// 随机数
  17. /// </summary>
  18. private const string NONCE = "nonce";
  19. /// <summary>
  20. /// 随机字符串
  21. /// </summary>
  22. private const string ECHOSTR = "echostr";
  23. /// <summary>
  24. ///
  25. /// </summary>
  26. private HttpRequest Request { get; set; }
  27. /// <summary>
  28. /// 构造函数
  29. /// </summary>
  30. /// <param name="request"></param>
  31. public WeiXinService(HttpRequest request)
  32. {
  33. this.Request = request;
  34. }
  35. /// <summary>
  36. /// 处理请求,产生响应
  37. /// </summary>
  38. /// <returns></returns>
  39. public string Response()
  40. {
  41. string method = Request.HttpMethod.ToUpper();
  42. //验证签名
  43. if (method == "GET")
  44. {
  45. if (CheckSignature())
  46. {
  47. return Request.QueryString[ECHOSTR];
  48. }
  49. else
  50. {
  51. return "error";
  52. }
  53. }
  54. //处理消息
  55. if (method == "POST")
  56. {
  57. return ResponseMsg();
  58. }
  59. else
  60. {
  61. return "无法处理";
  62. }
  63. }
  64. /// <summary>
  65. /// 处理请求
  66. /// </summary>
  67. /// <returns></returns>
  68. private string ResponseMsg()
  69. {
  70. string requestXml = CommonWeiXin.ReadRequest(this.Request);
  71. IHandler handler = HandlerFactory.CreateHandler(requestXml);
  72. if (handler != null)
  73. {
  74. return handler.HandleRequest();
  75. }
  76. return string.Empty;
  77. }
  78. /// <summary>
  79. /// 检查签名
  80. /// </summary>
  81. /// <param name="request"></param>
  82. /// <returns></returns>
  83. private bool CheckSignature()
  84. {
  85. string signature = Request.QueryString[SIGNATURE];
  86. string timestamp = Request.QueryString[TIMESTAMP];
  87. string nonce = Request.QueryString[NONCE];
  88. List<string> list = new List<string>();
  89. list.Add(TOKEN);
  90. list.Add(timestamp);
  91. list.Add(nonce);
  92. //排序
  93. list.Sort();
  94. //拼串
  95. string input = string.Empty;
  96. foreach (var item in list)
  97. {
  98. input += item;
  99. }
  100. //加密
  101. string new_signature = SecurityUtility.SHA1Encrypt(input);
  102. //验证
  103. if (new_signature == signature)
  104. {
  105. return true;
  106. }
  107. else
  108. {
  109. return false;
  110. }
  111. }
  112. }

在来看看我们的首先是如何捕获消息的。首页Default.ashx的代码如下

  1. public void ProcessRequest(HttpContext context)
  2. {
  3. context.Response.ContentType = "text/html";
  4. string postString = string.Empty;
  5. if (HttpContext.Current.Request.HttpMethod.ToUpper() == "POST")
  6. {
  7. //由微信服务接收请求,具体处理请求
  8. WeiXinService wxService = new WeiXinService(context.Request);
  9. string responseMsg = wxService.Response();
  10. context.Response.Clear();
  11. context.Response.Charset = "UTF-8";
  12. context.Response.Write(responseMsg);
  13. context.Response.End();
  14. }
  15. else
  16. {
  17. string token = "wei2414201";
  18. if (string.IsNullOrEmpty(token))
  19. {
  20. return;
  21. }
  22. string echoString = HttpContext.Current.Request.QueryString["echoStr"];
  23. string signature = HttpContext.Current.Request.QueryString["signature"];
  24. string timestamp = HttpContext.Current.Request.QueryString["timestamp"];
  25. string nonce = HttpContext.Current.Request.QueryString["nonce"];
  26. if (!string.IsNullOrEmpty(echoString))
  27. {
  28. HttpContext.Current.Response.Write(echoString);
  29. HttpContext.Current.Response.End();
  30. }
  31. }
  32. }

从上面的代码中我们可以看到WeiXinService.cs类中的消息相应至关重要。

  1. /// <summary>
  2. /// 处理请求
  3. /// </summary>
  4. /// <returns></returns>
  5. private string ResponseMsg()
  6. {
  7. string requestXml = CommonWeiXin.ReadRequest(this.Request);
  8. IHandler handler = HandlerFactory.CreateHandler(requestXml);
  9. if (handler != null)
  10. {
  11. return handler.HandleRequest();
  12. }
  13. return string.Empty;
  14. }

IHandler是一个消息处理接口,其下面有EventHandler,TextHandler处理类实现这个接口。代码如下

  1. /// <summary>
  2. /// 处理接口
  3. /// </summary>
  4. public interface IHandler
  5. {
  6. /// <summary>
  7. /// 处理请求
  8. /// </summary>
  9. /// <returns></returns>
  10. string HandleRequest();
  11. }

EventHandler

  1. class EventHandler : IHandler
  2. {
  3. /// <summary>
  4. /// 请求的xml
  5. /// </summary>
  6. private string RequestXml { get; set; }
  7. /// <summary>
  8. /// 构造函数
  9. /// </summary>
  10. /// <param name="requestXml"></param>
  11. public EventHandler(string requestXml)
  12. {
  13. this.RequestXml = requestXml;
  14. }
  15. /// <summary>
  16. /// 处理请求
  17. /// </summary>
  18. /// <returns></returns>
  19. public string HandleRequest()
  20. {
  21. string response = string.Empty;
  22. EventMessage em = EventMessage.LoadFromXml(RequestXml);
  23. if (em.Event.Equals("subscribe", StringComparison.OrdinalIgnoreCase))//用来判断是不是首次关注
  24. {
  25. PicTextMessage tm = new PicTextMessage();//我自己创建的一个图文消息处理类
  26. tm.ToUserName = em.FromUserName;
  27. tm.FromUserName = em.ToUserName;
  28. tm.CreateTime = CommonWeiXin.GetNowTime();
  29. response = tm.GenerateContent();
  30. }
  31. return response;
  32. }
  33. }

TextHandler

  1. /// <summary>
  2. /// 文本信息处理类
  3. /// </summary>
  4. public class TextHandler : IHandler
  5. {
  6. string openid { get; set; }
  7. string access_token { get; set; }
  8. /// <summary>
  9. /// 请求的XML
  10. /// </summary>
  11. private string RequestXml { get; set; }
  12. /// <summary>
  13. /// 构造函数
  14. /// </summary>
  15. /// <param name="requestXml">请求的xml</param>
  16. public TextHandler(string requestXml)
  17. {
  18. this.RequestXml = requestXml;
  19. }
  20. /// <summary>
  21. /// 处理请求
  22. /// </summary>
  23. /// <returns></returns>
  24. public string HandleRequest()
  25. {
  26. string response = string.Empty;
  27. TextMessage tm = TextMessage.LoadFromXml(RequestXml);
  28. string content = tm.Content.Trim();
  29. if (string.IsNullOrEmpty(content))
  30. {
  31. response = "您什么都没输入,没法帮您啊。";
  32. }
  33. else
  34. {
  35. string username = System.Configuration.ConfigurationManager.AppSettings["weixinid"].ToString();
  36. AccessToken token = AccessToken.Get(username);
  37. access_token = token.access_token;
  38. openid = tm.FromUserName;
  39. response = HandleOther(content);
  40. }
  41. tm.Content = response;
  42. //进行发送者、接收者转换
  43. string temp = tm.ToUserName;
  44. tm.ToUserName = tm.FromUserName;
  45. tm.FromUserName = temp;
  46. response = tm.GenerateContent();
  47. return response;
  48. }
  49. /// <summary>
  50. /// 处理其他消息
  51. /// </summary>
  52. /// <param name="tm"></param>
  53. /// <returns></returns>
  54. private string HandleOther(string requestContent)
  55. {
  56. string response = string.Empty;
  57. if (requestContent.Contains("你好") || requestContent.Contains("您好"))
  58. {
  59. response = "您也好~";
  60. }else if (requestContent.Contains("openid") || requestContent.Contains("id") || requestContent.Contains("ID"))//用来匹配用户输入的关键字
  61. {
  62. response = "你的Openid: "+openid;
  63. }
  64. else if (requestContent.Contains("token") || requestContent.Contains("access_token"))
  65. {
  66. response = "你的access_token: " + access_token;
  67. }else
  68. {
  69. response = "试试其他关键字吧。";
  70. }
  71. return response;
  72. }
  73. }

HandlerFactory

  1. /// <summary>
  2. /// 处理器工厂类
  3. /// </summary>
  4. public class HandlerFactory
  5. {
  6. /// <summary>
  7. /// 创建处理器
  8. /// </summary>
  9. /// <param name="requestXml">请求的xml</param>
  10. /// <returns>IHandler对象</returns>
  11. public static IHandler CreateHandler(string requestXml)
  12. {
  13. IHandler handler = null;
  14. if (!string.IsNullOrEmpty(requestXml))
  15. {
  16. //解析数据
  17. XmlDocument doc = new System.Xml.XmlDocument();
  18. doc.LoadXml(requestXml);
  19. XmlNode node = doc.SelectSingleNode("/xml/MsgType");
  20. if (node != null)
  21. {
  22. XmlCDataSection section = node.FirstChild as XmlCDataSection;
  23. if (section != null)
  24. {
  25. string msgType = section.Value;
  26. switch (msgType)
  27. {
  28. case "text":
  29. handler = new TextHandler(requestXml);
  30. break;
  31. case "event":
  32. handler = new EventHandler(requestXml);
  33. break;
  34. }
  35. }
  36. }
  37. }
  38. return handler;
  39. }
  40. }

 在这里基本的一些类已经完成了,现在我们来完成,关注我们的微信公众号,我们就发送一条图文消息,同时输入我们的一些关键字,返回一些消息,比如输入id返回用户的openid等等。

二.PicTextMessage

  1. public class PicTextMessage : Message
  2. {
  3. /// <summary>
  4. /// 模板静态字段
  5. /// </summary>
  6. private static string m_Template;
  7. /// <summary>
  8. /// 默认构造函数
  9. /// </summary>
  10. public PicTextMessage()
  11. {
  12. this.MsgType = "news";
  13. }
  14. /// <summary>
  15. /// 从xml数据加载文本消息
  16. /// </summary>
  17. /// <param name="xml"></param>
  18. public static PicTextMessage LoadFromXml(string xml)
  19. {
  20. PicTextMessage tm = null;
  21. if (!string.IsNullOrEmpty(xml))
  22. {
  23. XElement element = XElement.Parse(xml);
  24. if (element != null)
  25. {
  26. tm = new PicTextMessage();
  27. tm.FromUserName = element.Element(CommonWeiXin.FROM_USERNAME).Value;
  28. tm.ToUserName = element.Element(CommonWeiXin.TO_USERNAME).Value;
  29. tm.CreateTime = element.Element(CommonWeiXin.CREATE_TIME).Value;
  30. }
  31. }
  32. return tm;
  33. }
  34. /// <summary>
  35. /// 模板
  36. /// </summary>
  37. public override string Template
  38. {
  39. get
  40. {
  41. if (string.IsNullOrEmpty(m_Template))
  42. {
  43. LoadTemplate();
  44. }
  45. return m_Template;
  46. }
  47. }
  48. /// <summary>
  49. /// 生成内容
  50. /// </summary>
  51. /// <returns></returns>
  52. public override string GenerateContent()
  53. {
  54. this.CreateTime = CommonWeiXin.GetNowTime();
  55. string str= string.Format(this.Template, this.ToUserName, this.FromUserName, this.CreateTime);
  56. return str;
  57. }
  58. /// <summary>
  59. /// 加载模板
  60. /// </summary>
  61. private static void LoadTemplate()
  62. {
  63. m_Template= @"<xml>
  64. <ToUserName><![CDATA[{0}]]></ToUserName>
  65. <FromUserName><![CDATA[{1}]]></FromUserName>
  66. <CreateTime>{2}</CreateTime>
  67. <MsgType><![CDATA[news]]></MsgType>
  68. <ArticleCount>1</ArticleCount>
  69. <Articles>
  70. <item>
  71. <Title><![CDATA[有位停车欢迎你!]]></Title>
  72. <Description><![CDATA[如有问题请致电400-6238-136或直接在微信留言,我们将第一时间为您服务!]]></Description>
  73. <PicUrl><![CDATA[http://www.baidu.com/youwei.jpg]]></PicUrl>
  74. <Url><![CDATA[http://www.baidu.com]]></Url>
  75. </item>
  76. </Articles>
  77. </xml> ";
  78. }
  79. }

最后我们的效果如下所示;

以上所述就是本文的全部内容了,希望大家能够喜欢

人气教程排行