侯体宗的博客
  • 首页
  • Hyperf版
  • beego仿版
  • 人生(杂谈)
  • 技术
  • 关于我
  • 更多分类
    • 文件下载
    • 文字修仙
    • 中国象棋ai
    • 群聊
    • 九宫格抽奖
    • 拼图
    • 消消乐
    • 相册

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

微信(小程序)  /  管理员 发布于 7年前   163

一.前言

  微信公众平台的消息处理还是比较完善的,有最基本的文本消息,到图文消息,到图片消息,语音消息,视频消息,音乐消息其基本原理都是一样的,只不过所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> ";    }  }

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

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


  • 上一条:
    网站搜索框使用微信扫码功能
    下一条:
    .NET微信公众号开发之查询自定义菜单
  • 昵称:

    邮箱:

    0条评论 (评论内容有缓存机制,请悉知!)
    最新最热
    • 分类目录
    • 人生(杂谈)
    • 技术
    • linux
    • Java
    • php
    • 框架(架构)
    • 前端
    • ThinkPHP
    • 数据库
    • 微信(小程序)
    • Laravel
    • Redis
    • Docker
    • Go
    • swoole
    • Windows
    • Python
    • 苹果(mac/ios)
    • 相关文章
    • 微信模板消息改版后发送规则记录(微信订阅消息参数值内容限制说明)(1个评论)
    • 微信支付v3对接所需工具及命令(0个评论)
    • 2023年9月1日起:微信小程序必须备案才能上线运营(0个评论)
    • 腾讯官方客服回应了:微信好友上限约10000个!(1个评论)
    • 2023年做微信小程序的老铁注意:新增收费项、微信小程序获取手机号也收费了(2个评论)
    • 近期文章
    • 在go语言中使用api.geonames.org接口实现根据国际邮政编码获取地址信息功能(1个评论)
    • 在go语言中使用github.com/signintech/gopdf实现生成pdf分页文件功能(0个评论)
    • gmail发邮件报错:534 5.7.9 Application-specific password required...解决方案(0个评论)
    • 欧盟关于强迫劳动的规定的官方举报渠道及官方举报网站(0个评论)
    • 在go语言中使用github.com/signintech/gopdf实现生成pdf文件功能(0个评论)
    • Laravel从Accel获得5700万美元A轮融资(0个评论)
    • 在go + gin中gorm实现指定搜索/区间搜索分页列表功能接口实例(0个评论)
    • 在go语言中实现IP/CIDR的ip和netmask互转及IP段形式互转及ip是否存在IP/CIDR(0个评论)
    • PHP 8.4 Alpha 1现已发布!(0个评论)
    • Laravel 11.15版本发布 - Eloquent Builder中添加的泛型(0个评论)
    • 近期评论
    • 122 在

      学历:一种延缓就业设计,生活需求下的权衡之选中评论 工作几年后,报名考研了,到现在还没认真学习备考,迷茫中。作为一名北漂互联网打工人..
    • 123 在

      Clash for Windows作者删库跑路了,github已404中评论 按理说只要你在国内,所有的流量进出都在监控范围内,不管你怎么隐藏也没用,想搞你分..
    • 原梓番博客 在

      在Laravel框架中使用模型Model分表最简单的方法中评论 好久好久都没看友情链接申请了,今天刚看,已经添加。..
    • 博主 在

      佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 @1111老铁这个不行了,可以看看近期评论的其他文章..
    • 1111 在

      佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 网站不能打开,博主百忙中能否发个APP下载链接,佛跳墙或极光..
    • 2016-10
    • 2017-10
    • 2018-01
    • 2020-03
    • 2021-06
    • 2021-10
    • 2022-03
    • 2023-02
    • 2023-06
    • 2023-07
    • 2023-08
    • 2023-10
    • 2023-11
    Top

    Copyright·© 2019 侯体宗版权所有· 粤ICP备20027696号 PHP交流群

    侯体宗的博客