zoukankan      html  css  js  c++  java
  • Senparc.Weixin.MP SDK 微信公众平台开发教程(六):了解MessageHandler

    上一篇《Senparc.Weixin.MP SDK 微信公众平台开发教程(五):使用Senparc.Weixin.MP SDK》我们讲述了如何使用Senparc.Weixin.MP SDK对接微信最基础的验证API,这一篇我们将具体讲一下这个SDK处理微信消息的核心:MessageHandler。

        有关MessageHandler的实现原理和说明,在这篇Wiki中已经说得比较详细了,这里用代码演示一下。

        延续上一篇的代码,我们继续为项目添加一个CustomMessageHandle.cs类:

        CustomMessageHandle.cs需要继承Senparc.Weixin.MP.MessageHandlers<TC>这个抽象类,并实现部分方法。最初步的CustomMessageHandle.cs代码
    可能如下:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    using System;
    using System.Collections.Generic;
    using System.IO;
    using System.Linq;
    using System.Web;
    using Senparc.Weixin.MP.Context;
    using Senparc.Weixin.MP.Entities;
    using Senparc.Weixin.MP.MessageHandlers;
     
    namespace Senparc.Weixin.MP.Sample.Weixin
    {
        public class CustomMessageHandler : MessageHandler<MessageContext>
        {
            public CustomMessageHandler(Stream inputStream)
                base(inputStream)
            {
     
            }
     
            public override IResponseMessageBase DefaultResponseMessage(IRequestMessageBase requestMessage)
            {
                var responseMessage = base.CreateResponseMessage<ResponseMessageText>(); //ResponseMessageText也可以是News等其他类型
                responseMessage.Content = "这条消息来自DefaultResponseMessage。";
                return responseMessage;
            }
        }
    }

      

        我们可以看到必须要重写实现的抽象方法名为DefaultResponseMessage(),这一条信息用于返回一条的消息,假如对应类型(如语音)的微信消息没有被代码处理,那么默认会返回这里的结果。

        在DefaultResponseMessage()方法中,我们看到这样一句:

    1
    var responseMessage = base.CreateResponseMessage<ResponseMessageText>(); //ResponseMessageText也可以是News等其他类型

      这里的CreateResponseMessage<T>方法即创建一个返回对象,T可以为以下类型的任意一个,分别对应了不同的返回类型:

    ResponseMessageText - 对应文本消息

    ResponseMessageNews - 对应图文消息

    ResponseMessageMusic - 对应音乐消息

        关于上述3种类型参数的设置方法,可以看开源项目的Demo,这里不再重复:https://github.com/JeffreySu/WeiXinMPSDK

        那么我们如何处理用户发过来的文字信息呢?

        很简单——重写一个OnTextRequest方法即可:

    1
    2
    3
    4
    5
    6
    7
    public override IResponseMessageBase OnTextRequest(RequestMessageText requestMessage)
    {
        var responseMessage = base.CreateResponseMessage<ResponseMessageText>();
        responseMessage.Content = "您的OpenID是:" + requestMessage.FromUserName      //这里的requestMessage.FromUserName也可以直接写成base.WeixinOpenId
                                "。 您发送了文字信息:" + requestMessage.Content;  // 用于换行,requestMessage.Content即用户发过来的文字内容
        return responseMessage;
    }

      这个方法中可以自由发挥,比如读取数据库、判断关键字,甚至返回不同的ResponseMessageXX类型(只要最终的类型都是在IResponseMessageBase接口下的即可)。

        与OnTextRequest对应,如果我们要处理语音、地理位置、菜单等类型的消息,只需要重写对应的方法,可以重写的方法如下:

    复制代码
            public virtual IResponseMessageBase OnImageRequest(RequestMessageImage requestMessage);
            public virtual IResponseMessageBase OnLinkRequest(RequestMessageLink requestMessage);
            public virtual IResponseMessageBase OnLocationRequest(RequestMessageLocation requestMessage);
            public virtual IResponseMessageBase OnTextRequest(RequestMessageText requestMessage);
            public virtual IResponseMessageBase OnVoiceRequest(RequestMessageVoice requestMessage);
            public virtual IResponseMessageBase OnVideoRequest(RequestMessageVideo requestMessage);
    
    
            public virtual IResponseMessageBase OnEvent_ClickRequest(RequestMessageEvent_Click requestMessage);
            public virtual IResponseMessageBase OnEvent_ViewRequest(RequestMessageEvent_View requestMessage);
            public virtual IResponseMessageBase OnEvent_EnterRequest(RequestMessageEvent_Enter requestMessage);
            public virtual IResponseMessageBase OnEvent_LocationRequest(RequestMessageEvent_Location requestMessage);
            public virtual IResponseMessageBase OnEvent_SubscribeRequest(RequestMessageEvent_Subscribe requestMessage);
            public virtual IResponseMessageBase OnEvent_UnsubscribeRequest(RequestMessageEvent_Unsubscribe requestMessage);
            public virtual IResponseMessageBase OnEvent_ScanRequest(RequestMessageEvent_Scan requestMessage)
            public virtual IResponseMessageBase OneEvent_MassSendJobFinisRequest(RequestMessageEvent_MassSendJobFinish requestMessage)
    复制代码

        其中OnEvent_XX对应的都是Event请求的子类型。

        在CustomMessageHandler的基类设置的时候,我们看到使用了一个叫MessageContext的泛型(MessageHandler<MessageContext>),这个MessageContext是SDK提供的一个默认的消息上下文处理类,这个类已经能够处理最基础的情况,如果您的应用不是很复杂,那么直接用这个类就行了。如果项目比较复杂,您也可以根据自己的需要写一个自己的类(继承IMessageContext接口),或继承这个类在扩展一些更多的属性(例如工作流和分布式缓存等等)。

        至此我们已经使用MassageHandler处理所有微信用户发送过来的请求。

        下面介绍一些MassageHandler的“秘密武器”。

    • OnExecuting()和OnExecuted()

      我们可以直接重写这两个方法。其中OnExecuting会在所有消息处理方法(如OnTextRequest,OnVoiceRequest等)执行之前执行,这个过程中,我们可以把CancelExecute设为true,来中断后面所有方法的执行(包括OnExecuted),例如:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    public override void OnExecuting()
    {
        if (RequestMessage.FromUserName == "olPjZjsXuQPJoV0HlruZkNzKc91E")
        {
            CancelExcute = true//终止此用户的对话
         
            //如果没有下面的代码,用户不会收到任何回复,因为此时ResponseMessage为null
     
            //添加一条固定回复
            var responseMessage = CreateResponseMessage<ResponseMessageText>();
            responseMessage.Content = "Hey!你已经被拉黑啦!";
     
            ResponseMessage = responseMessage;//设置返回对象
        }
    }

      如果OnExecuting中没有中断,当例如OnTextRequest方法执行完毕之后(或执行了默认方法),OnExecuted()方法将会触发,我们也可以对应地重写。要注意的是,在OnExecuted()方法内,ResponseMessage已经被赋了返回值。

  • 相关阅读:
    高斯消元算法
    Fermat小定理的证明
    Pollard Rho 算法简介
    做一些无聊的题
    永远不要相信自己的傲慢
    笔记-数据结构进阶
    笔记-区间问题
    线段树板子
    [DarkBZOJ3694] 最短路
    [CF321D] Ciel and Flipboard
  • 原文地址:https://www.cnblogs.com/Alex80/p/4261613.html
Copyright © 2011-2022 走看看