Home  >  Article  >  WeChat Applet  >  Detailed explanation of the public account message processing method for developing WeChat public accounts using .NET

Detailed explanation of the public account message processing method for developing WeChat public accounts using .NET

高洛峰
高洛峰Original
2017-03-14 14:09:191754browse

This article tells you about the message processing of public accounts in the development of .net WeChat public accounts. It is very detailed. Friends in need can refer to it.

1. Foreword

The message processing of the WeChat public platform is relatively complete, ranging from the most basic text messages, to graphic messages, to picture messages, and voice messages , Video messages, and music messages. The basic principles are the same, but the xml data posted is different. Before processing the message, we must read it carefully. The official Documentation: http://mp.weixin.qq.com/wiki/14/89b871b5466b19b3efa4ada8e577d45e.html. First we start with the most basic text message processing.


<xml>
<ToUserName><![CDATA[toUser]]></ToUserName>
<FromUserName><![CDATA[fromUser]]></FromUserName>
<CreateTime>12345678</CreateTime>
<MsgType><![CDATA[text]]></MsgType>
<Content><![CDATA[你好]]></Content>
</xml>

We can see that this is the most basic pattern of message processing, with sender, receiver, creation time, type, content, etc.

First we create a message processing class. This class is used to capture all message requests and process different message replies according to different message request types.


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;
      }
    }
  }

Let’s take a look at how we capture the message first. The code of Default.ashx on the home page is as follows


    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();
        }
      }


    }

From the above code we can see that the messages in the WeiXinService.cs class are very important.


    /// <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 is a message processing interface , underneath it is EventHandler, and the TextHandler processing class implements this interface. The code is as follows


  /// <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;
    }
  }

Some basic classes here have been completed. Now let’s complete it. Follow our WeChat official account and we will send a graphic message. At the same time Enter some of our keywords and return some messages, such as entering the id to return the user's openid, etc.

二.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.php.cn/]]></PicUrl>
                <Url><![CDATA[http://www.php.cn/]]></Url>
                </item>
              </Articles>
            </xml> ";
    }
  }

Finally our effect is as follows;

Detailed explanation of the public account message processing method for developing WeChat public accounts using .NETDetailed explanation of the public account message processing method for developing WeChat public accounts using .NET

The above is the entire content of this article, I hope you all like it

The above is the detailed content of Detailed explanation of the public account message processing method for developing WeChat public accounts using .NET. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn