.NET微信开发之公众号消息处理的代码示例

互联网 17-4-25
一.前言

微信公众平台的消息处理还是比较完善的,有最基本的文本消息,到图文消息,到图片消息,语音消息,视频消息,音乐消息其基本原理都是一样的,只不过所post的xml数据有所差别,在处理消息之前,我们要认真阅读,官方给我们的文档: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> ";      }    }

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

以上就是.NET微信开发之公众号消息处理的代码示例的详细内容,更多内容请关注技术你好其它相关文章!

来源链接:
免责声明:
1.资讯内容不构成投资建议,投资者应独立决策并自行承担风险
2.本文版权归属原作所有,仅代表作者本人观点,不代表本站的观点或立场
标签: 开发
上一篇:php获取远程图片并下载保存到本地的方法分析 下一篇:ASP.NET实现QQ、微信、新浪微博OAuth2.0授权登录的实例详解

相关资讯