Project GitHub address: https://github.com/Andyahui/xgyxsh_WeiXin
One: WeChat XML POST request processing
Yesterday we became a developer, which shows that the get request can be processed to the end and is processed accordingly. The following is what we do through the browser The URL we configured is browsed to.
We can find that the return value set in the get request appears here, indicating that our test is successful. Next we need to set the Action corresponding to the POST request.
Note: Since every interaction between our WeChat and the website server is through a POST request to get what we want, we must encrypt the transmission.
/// <summary> /// 用户发送消息后,微信平台自动Post一个请求到这里,并等待响应XML。 /// PS:此方法为简化方法,效果与OldPost一致。 /// v0.8之后的版本可以结合Senparc.Weixin.MP.MvcExtension扩展包,使用WeixinResult,见MiniPost方法。 /// </summary> [HttpPost] [ActionName("Index")] public ActionResult Post(PostModel postModel) { postModel.Token = Token; // postModel.EncodingAESKey = ""; //根据自己后台的设置保持一致 // postModel.AppId = AppId; //根据自己后台的设置保持一致 //验证数字签名 if (!CheckSignature.Check(postModel.Signature, postModel.Timestamp, postModel.Nonce, Token)) { //??? 这里有问题,要是不注释的话,就会在这里出错,也就是数字签名有问题。 //return Content("参数错误!"); } // 1:自定义MessageHandler,对微信请求的详细判断操作都在这里面。 实例化了一个类 var messageHandler = new CustomMessageHandle(Request.InputStream, postModel); //接收消息 // 2:执行微信处理过程----执行完这里之后ResponseMessage才会有值。 messageHandler.Execute(); // 3:return new FixWeixinBugWeixinResult(messageHandler); 这个有换行的问题。 //return new FixWeixinBugWeixinResult(messageHandler.ToString()); // 3:注意第三个----为了解决官方微信5.0软件换行bug暂时添加的方法,平时用下面一个方法即可 return new WeixinResult(messageHandler); //v0.8+ }
We can clearly see the meaning of each line above. I have a question here. If the digital signature is verified without annotating the if judgment, it will directly display "Parameter error" "The following operations will not continue, but there is no comment in the official blog. I don't know why? ? (Ask God for answers.)
There are three main steps above:
First, the CustomMessageHandle object is instantiated and the corresponding parameters are passed. The corresponding CTOR is initialized, then its Execute() method is called, and finally the corresponding CustomMessageHandle object is returned by instantiating WeixinResult. At this time, the object contains the logical processing method of our website's backend.
This is how our POST request is processed , every time the xml information forwarded by the WeChat server will be forwarded here again using the POST request form, we will process it.
2: Understand MessageHandler
To complete WeChat development, you need to understand the key classes in the SDK. The following is simple Let’s talk about MessageHandler;
MessageHandler is the core of SDK processing messages. It mainly handles POST requests accordingly. Logical judgments can also be made. To put it bluntly, all our business logic is performed under this class.
namespace XGY_WeiXin.WeiXinHelper { public class CustomMessageHandle : MessageHandler<CustomMessageContext> { //PostModel:表示的都是从微信服务器里面得到的值,时间戳,字符串等。(WeiXinController中使用过) //构造函数的inputStream用于接收来自微信服务器的请求流(如果需要在外部处理,这里也可以传入XDocument)。 public CustomMessageHandle(Stream inputSrream,PostModel postModel):base(inputSrream,postModel) { } /// <summary> /// 必须实现抽象的类------作用:用于放回一条信息,当没有对应类型的微信消息没有被代码处理,那么默认会执行返回这里的结果。 /// </summary> /// <param name="requestMessage">请求消息</param> /// <returns></returns> public override IResponseMessageBase DefaultResponseMessage(IRequestMessageBase requestMessage) { //CreateResponseMessage<T> 这里是创建一个放回的对象,代表不同的类型, var responseMessage = base.CreateResponseMessage<ResponseMessageText>();//ResponseMessageText可以更换为别的类型 responseMessage.Content = "这条消息来自DefaultResponseMessage。"; return responseMessage; } /// <summary> ///1: 处理用户发送过来的文字消息。重写OnTextRequest方法。 /// --------(总结:)方法里面可以自由发挥,读取DB,判断关键字,甚至返回不同的ResponseMessageXX类型(只要最终的类型都是在IResponseMessageBase接口下的即可)。 /// </summary> /// <param name="requestMessage">请求消息</param> /// <returns></returns> public override IResponseMessageBase OnTextRequest(RequestMessageText requestMessage) { //CreateResponseMessage<类型>根据当前的RequestMessage创建指定类型的ResponseMessage;创建相应消息. var responseMessage = base.CreateResponseMessage<ResponseMessageText>(); responseMessage.Content = "您的OpenID是:" + requestMessage.FromUserName + "。\r\t您发送了文字信息:" + requestMessage.Content; return responseMessage; } } }
Analyze from top to bottom. I found that it is inherited from MessageHandler but there is a CustomMessageContext behind it. At this time, I have a new understanding of MessageHandler. This thing turns out to be a generic abstract class. We need to fill in a type in it. Check the official description and say that this CustomMessageContext is a custom I haven’t studied carefully what the defined context class is. Let’s look at the official introduction (WiKi). Then below is a CTOR, which is mainly used when instantiating
Three: Custom context CustomMessageContext
下面是自定义上下文类CustomMessageContext,主要是继承自MessageContext
/// <summary> /// 自定义的上下文类---->处理单个用户的对话状态。 /// </summary> public class CustomMessageContext : MessageContext<IRequestMessageBase,IResponseMessageBase> { public CustomMessageContext() { base.MessageContextRemoved+=CustomMessageContext_MessageContextRemoved; } /// <summary> /// 当上下文过期,被移除的时候触发的时间 /// </summary> private void CustomMessageContext_MessageContextRemoved(object sender, Senparc.Weixin.Context.WeixinContextRemovedEventArgs<IRequestMessageBase, IResponseMessageBase> e) { /* 注意,这个事件不是实时触发的(当然你也可以专门写一个线程监控) * 为了提高效率,根据WeixinContext中的算法,这里的过期消息会在过期后下一条请求执行之前被清除 */ var messageContext = e.MessageContext as CustomMessageContext; if (messageContext==null) { //如果是正常的调用,messageContext不会为null return ; } //TODO:这里根据需要执行消息过期时候的逻辑,下面的代码仅供参考 //Log.InfoFormat("{0}的消息上下文已过期",e.OpenId); //api.SendMessage(e.OpenId, "由于长时间未搭理客服,您的客服状态已退出!"); } }
解释参考官方给的解释,版本升级了(WiKi),我觉得这里以后还是会做大文章的。
四:微信测试号效果展示
此时我们大体的底层框架就搭建成功了,我们发布部署到服务器上面就可以看到文本处理的响应了。
这是微信的二维码可以关注下,可以实现简单的互动。
更多微信开发系列----02:实现POST请求响应 相关文章请关注PHP中文网!