上一篇《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代碼
可能如下:
using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Web; using Senparc.Weixin.MP.Entities; using Senparc.Weixin.MP.MessageHandlers; namespace Senparc.Weixin.MP.Sample.Weixin { public class CustomMessageHandler : MessageHandler<CustomMessageContext> { public CustomMessageHandler(Stream inputStream, PostModel postModel) : base(inputStream, postModel) { } public override IResponseMessageBase DefaultResponseMessage(IRequestMessageBase requestMessage) { var responseMessage = base.CreateResponseMessage<ResponseMessageText>(); //ResponseMessageText也可以是News等其他類型 responseMessage.Content = "這條消息來自DefaultResponseMessage。"; return responseMessage; } } }
我們可以看到必須要重寫實現的抽象方法名為DefaultResponseMessage(),這一條信息用於返回一條的消息,假如對應類型(如語音)的微信消息沒有被代碼處理,那么默認會返回這里的結果。
在DefaultResponseMessage()方法中,我們看到這樣一句:
var responseMessage = base.CreateResponseMessage<ResponseMessageText>(); //ResponseMessageText也可以是News等其他類型
這里的CreateResponseMessage<T>方法即創建一個返回對象,T可以為以下類型的任意一個,分別對應了不同的返回類型:
ResponseMessageText - 對應文本消息
ResponseMessageNews - 對應圖文消息
ResponseMessageMusic - 對應音樂消息
ResponseMessageXXX - 其他類型以此類推
關於上述所有類型參數的設置方法,可以看開源項目的Demo,這里不再重復:https://github.com/JeffreySu/WeiXinMPSDK。
那么我們如何處理用戶發過來的文字信息呢?
很簡單——重寫一個OnTextRequest方法即可:
public override IResponseMessageBase OnTextRequest(RequestMessageText requestMessage) { var responseMessage = base.CreateResponseMessage<ResponseMessageText>(); responseMessage.Content = "您的OpenID是:" + requestMessage.FromUserName //這里的requestMessage.FromUserName也可以直接寫成base.WeixinOpenId + "。\r\n您發送了文字信息:" + requestMessage.Content; //\r\n用於換行,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),例如:
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已經被賦了返回值。
- 處理對話上下文
CustomMessageHandler繼承了類MessageHandler<CustomMessageContext>,其中的CustomMessageContext是一個我們自定義的上下文類,用於處理單個用戶的對話狀態。這一個功能我們會放到下一篇單獨講述:《Senparc.Weixin.MP SDK 微信公眾平台開發教程(七):解決用戶上下文(Session)問題》。
系列教程索引
地址:http://www.cnblogs.com/szw/archive/2013/05/14/weixin-course-index.html
- Senparc.Weixin.MP SDK 微信公眾平台開發教程(一):微信公眾平台注冊
- Senparc.Weixin.MP SDK 微信公眾平台開發教程(二):成為開發者
- Senparc.Weixin.MP SDK 微信公眾平台開發教程(三):微信公眾平台開發驗證
- Senparc.Weixin.MP SDK 微信公眾平台開發教程(四):Hello World
- Senparc.Weixin.MP SDK 微信公眾平台開發教程(五):使用Senparc.Weixin.MP SDK
- Senparc.Weixin.MP SDK 微信公眾平台開發教程(六):了解MessageHandler
- Senparc.Weixin.MP SDK 微信公眾平台開發教程(七):解決用戶上下文(Session)問題
- Senparc.Weixin.MP SDK 微信公眾平台開發教程(八):通用接口說明
- Senparc.Weixin.MP SDK 微信公眾平台開發教程(九):自定義菜單接口說明
- Senparc.Weixin.MP SDK 微信公眾平台開發教程(十):多客服接口說明
- Senparc.Weixin.MP SDK 微信公眾平台開發教程(十一):高級接口說明
- Senparc.Weixin.MP SDK 微信公眾平台開發教程(十二):OAuth2.0說明
- Senparc.Weixin.MP SDK 微信公眾平台開發教程(十三):地圖相關接口說明
- Senparc.Weixin.MP SDK 微信公眾平台開發教程(十四):請求消息去重
- Senparc.Weixin.MP SDK 微信公眾平台開發教程(十五):消息加密
- Senparc.Weixin.MP SDK 微信公眾平台開發教程(十六):AccessToken自動管理機制
- Senparc.Weixin.MP SDK 微信公眾平台開發教程(十七):個性化菜單接口說明
- Senparc.Weixin.MP SDK 微信公眾平台開發教程(十八):Web代理功能
- Senparc.Weixin.MP SDK 微信公眾平台開發教程(十九):MessageHandler 的未知類型消息處理
- Senparc.Weixin.MP SDK 微信公眾平台開發教程(二十):使用菜單消息功能
- Senparc.Weixin.MP SDK 微信公眾平台開發教程(二十一):在小程序中使用 WebSocket (.NET Core)
- Senparc.Weixin.MP SDK 微信公眾平台開發教程(二十二):如何安裝 Nuget(dll) 后使用項目源代碼調試