热门标签 | HotTags
当前位置:  开发笔记 > 前端 > 正文

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

本文给大家讲述的是在.net微信公众号开发中的公众号的消息处理的相关内容,非常详细,有需要的小伙伴可以参考下。

一.前言

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




12345678




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

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

public class WeiXinService
  {
    /// 
    /// TOKEN
    /// 
    private const string TOKEN = "finder";
    /// 
    /// 签名
    /// 
    private const string SIGNATURE = "signature";
    /// 
    /// 时间戳
    /// 
    private const string TIMESTAMP = "timestamp";
    /// 
    /// 随机数
    /// 
    private const string NOnCE= "nonce";
    /// 
    /// 随机字符串
    /// 
    private const string ECHOSTR = "echostr";
    /// 
    /// 
    /// 
    private HttpRequest Request { get; set; }
    /// 
    /// 构造函数
    /// 
    /// 
    public WeiXinService(HttpRequest request)
    {
      this.Request = request;
    }
    /// 
    /// 处理请求,产生响应
    /// 
    /// 
    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 "无法处理";
      }
    }

    /// 
    /// 处理请求
    /// 
    /// 
    private string ResponseMsg()
    {
      string requestXml = CommonWeiXin.ReadRequest(this.Request);
      IHandler handler = HandlerFactory.CreateHandler(requestXml);
   
      if (handler != null)
      {
        return handler.HandleRequest();
      }

      return string.Empty;
    }
    /// 
    /// 检查签名
    /// 
    /// 
    /// 
    private bool CheckSignature()
    {
      string signature = Request.QueryString[SIGNATURE];
      string timestamp = Request.QueryString[TIMESTAMP];
      string nOnce= Request.QueryString[NONCE];

      List list = new List();
      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类中的消息相应至关重要。

    /// 
    /// 处理请求
    /// 
    /// 
    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处理类实现这个接口。代码如下

  /// 
  /// 处理接口
  /// 
  public interface IHandler
  {
    /// 
    /// 处理请求
    /// 
    /// 
    string HandleRequest();
  }

EventHandler

class EventHandler : IHandler
  {
    /// 
    /// 请求的xml
    /// 
    private string RequestXml { get; set; }
    /// 
    /// 构造函数
    /// 
    /// 
    public EventHandler(string requestXml)
    {
      this.RequestXml = requestXml;
    }
    /// 
    /// 处理请求
    /// 
    /// 
    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

  /// 
  /// 文本信息处理类
  /// 
  public class TextHandler : IHandler
  {
    string openid { get; set; }
    string access_token { get; set; }

    /// 
    /// 请求的XML
    /// 
    private string RequestXml { get; set; }
    /// 
    /// 构造函数
    /// 
    /// 请求的xml
    public TextHandler(string requestXml)
    {
      this.RequestXml = requestXml;
    }
    /// 
    /// 处理请求
    /// 
    /// 
    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;
    }
    /// 
    /// 处理其他消息
    /// 
    /// 
    /// 
    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

  /// 
  /// 处理器工厂类
  /// 
  public class HandlerFactory
  {
    /// 
    /// 创建处理器
    /// 
    /// 请求的xml
    /// IHandler对象
    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
  {
    /// 
    /// 模板静态字段
    /// 
    private static string m_Template;

    /// 
    /// 默认构造函数
    /// 
    public PicTextMessage()
    {
      this.MsgType = "news";
    }
    /// 
    /// 从xml数据加载文本消息
    /// 
    /// 
    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;
    }
    /// 
    /// 模板
    /// 
    public override string Template
    {
      get
      {
        if (string.IsNullOrEmpty(m_Template))
        {
          LoadTemplate();
        }

        return m_Template;
      }
    }
    /// 
    /// 生成内容
    /// 
    /// 
    public override string GenerateContent()
    {
      this.CreateTime = CommonWeiXin.GetNowTime();
      string str= string.Format(this.Template, this.ToUserName, this.FromUserName, this.CreateTime);
      return str;
    }


    /// 
    /// 加载模板
    /// 
    private static void LoadTemplate()
    {
      m_Template= @"
              
              
              {2}
              
              1
              
                
                 
                
                
                
                
              
             ";
    }
  }

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

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


推荐阅读
  • 国内BI工具迎战国际巨头Tableau,稳步崛起
    尽管商业智能(BI)工具在中国的普及程度尚不及国际市场,但近年来,随着本土企业的持续创新和市场推广,国内主流BI工具正逐渐崭露头角。面对国际品牌如Tableau的强大竞争,国内BI工具通过不断优化产品和技术,赢得了越来越多用户的认可。 ... [详细]
  • 本文详细分析了JSP(JavaServer Pages)技术的主要优点和缺点,帮助开发者更好地理解其适用场景及潜在挑战。JSP作为一种服务器端技术,广泛应用于Web开发中。 ... [详细]
  • 本文介绍了如何利用JavaScript或jQuery来判断网页中的文本框是否处于焦点状态,以及如何检测鼠标是否悬停在指定的HTML元素上。 ... [详细]
  • Python自动化处理:从Word文档提取内容并生成带水印的PDF
    本文介绍如何利用Python实现从特定网站下载Word文档,去除水印并添加自定义水印,最终将文档转换为PDF格式。该方法适用于批量处理和自动化需求。 ... [详细]
  • XNA 3.0 游戏编程:从 XML 文件加载数据
    本文介绍如何在 XNA 3.0 游戏项目中从 XML 文件加载数据。我们将探讨如何将 XML 数据序列化为二进制文件,并通过内容管道加载到游戏中。此外,还会涉及自定义类型读取器和写入器的实现。 ... [详细]
  • 基于KVM的SRIOV直通配置及性能测试
    SRIOV介绍、VF直通配置,以及包转发率性能测试小慢哥的原创文章,欢迎转载目录?1.SRIOV介绍?2.环境说明?3.开启SRIOV?4.生成VF?5.VF ... [详细]
  • 解决JAX-WS动态客户端工厂弃用问题并迁移到XFire
    在处理Java项目中的JAR包冲突时,我们遇到了JaxWsDynamicClientFactory被弃用的问题,并成功将其迁移到org.codehaus.xfire.client。本文详细介绍了这一过程及解决方案。 ... [详细]
  • 本文探讨了在通过 API 端点调用时,使用猫鼬(Mongoose)的 findOne 方法总是返回 null 的问题,并提供了详细的解决方案和建议。 ... [详细]
  • 本文将深入探讨PHP编程语言的基本概念,并解释PHP概念股的含义。通过详细解析,帮助读者理解PHP在Web开发和股票市场中的重要性。 ... [详细]
  • 探讨如何真正掌握Java EE,包括所需技能、工具和实践经验。资深软件教学总监李刚分享了对毕业生简历中常见问题的看法,并提供了详尽的标准。 ... [详细]
  • 程序员妻子吐槽:丈夫北漂8年终薪3万,存款情况令人意外
    一位程序员的妻子在网上分享了她丈夫在北京工作八年的经历,月薪仅3万元,存款情况却出乎意料。本文探讨了高学历人才在大城市的职场现状及生活压力。 ... [详细]
  • QBlog开源博客系统:Page_Load生命周期与参数传递优化(第四部分)
    本教程将深入探讨QBlog开源博客系统的Page_Load生命周期,并介绍一种简洁的参数传递重构方法。通过视频演示和详细讲解,帮助开发者更好地理解和应用这些技术。 ... [详细]
  • 本文详细介绍了Java Web应用程序中的过滤器(Filter)功能,包括其作用、实现方式及配置方法。过滤器可以在请求到达目标资源之前对其进行预处理,并在响应返回给客户端之前进行后处理。 ... [详细]
  • 本文介绍了多个关于JavaScript的书籍资源、实用工具和编程实例,涵盖从入门到进阶的各个阶段,帮助读者全面提升JavaScript编程能力。 ... [详细]
  • 分享一个简化版的Silverlight链接图项目:Link Map Simplified
    本文介绍了一个使用Silverlight开发的可视化工具,主要用于展示和操作复杂的实体关系图(Graph)。该工具在犯罪调查系统中得到了广泛应用,帮助用户直观地获取和理解相关信息。 ... [详细]
author-avatar
小丹巛丹布莱妮
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有