博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
.net微信公众号开发——消息与事件
阅读量:4544 次
发布时间:2019-06-08

本文共 3503 字,大约阅读时间需要 11 分钟。

1 消息(事件)概况

当普通微信用户向公众号发消息或者微信服务器向公众号推送事件时,微信服务器将POST消息(事件)的XML数据包到开发者填写的公众号服务器URL上;公众号服务器然后对消息作出响应。
1.1 消息的流转过程
为了便于区分,我们将微信服务器发往公众号服务器的消息称为请求(Request)消息;将公众号服务器发往微信服务器的消息称为响应(Response)消息;将推送事件看成特殊的请求消息。
请求与响应消息的流转过程如下图所示:
1.2 请求消息
请求消息有很多种,我们为其一一建立了对应的类,类层次结构如下图所示:
有些请求消息,我们可以做出响应,有些则不能,详见下表:
消息类型 是否事件 能够被动回复 备注
文本 × √
图片 × √
声音 × √
视频 × 未知 接收不到视频消息,不知道是否能被动回复
地理位置 × √
链接 × √
订阅 √ ×
取消订阅 √ ×
扫描二维码 √ ×
上报地理位置 √ ×
点击菜单拉取消息 √ √
点击菜单跳转链接 √ ×
点击菜单扫码推 √ ×
点击菜单扫码等待回复 √ √
点击菜单系统发图 √ 未知 接收不到系统发图事件;微信服务器会发送图片消息,可回复
点击菜单拍照或相册发图 √ × 微信服务器会发送图片消息,可回复
点击菜单微信发图 √ × 微信服务器会发送图片消息,可回复
点击菜单选择地理位置 √ × 微信服务器会发送地理位置消息,可回复
推送群发消息结果 √ ×
推送发送模板消息结果 √ ×
1.3 响应消息
响应消息的类层次结构如下图所示:
2 验证消息的真实性
公众号服务器接收到微信服务器的请求之后,第一件事情是验证消息的真实性。
Utility.CheckSignature方法用于验证消息签名是否正确。
示例如下:
///
/// 验证消息的有效性
///
/// 
/// 如果消息有效,返回true;否则返回false。
private bool Validate(HttpContext context)
{
string username = RequestEx.TryGetQueryString("username"); //在接口配置的URL中加入了username参数,表示哪个微信公众号
AccountInfo account = AccountInfoCollection.GetAccountInfo(username);
if (account == null)
return false;
string token = account.Token;
string signature = RequestEx.TryGetQueryString("signature");
string timestamp = RequestEx.TryGetQueryString("timestamp");
string nonce = RequestEx.TryGetQueryString("nonce");
if (string.IsNullOrWhiteSpace(signature) || string.IsNullOrWhiteSpace(timestamp) || string.IsNullOrWhiteSpace(nonce))
return false;
return xrwang.weixin.PublicAccount.Utility.CheckSignature(signature, token, timestamp, nonce);
}
验证消息真实性
3 解析消息
如果消息签名通过验证,我们需要将XML格式的消息文本解析成请求消息对象,RequestMessageHelper类用于完成这项工作。
RequestMessageHelper helper = new RequestMessageHelper(context.Request);
if(helper.Message != null)
{
//消息解析成功,对它进行处理
}
消息解析成功之后,helper.Message为消息基类RequestBaseMessage,我们可以根据属性MsgType及Event判断到底是哪种消息(事件),并转换成适当的子类型。例如:
RequestBaseMessage bm=helper.Message;
switch(bm.MsgType)
{
case RequestMessageTypeEnum.text: //文本消息
HandleTextMessage((RequestTextMessage)bm);
break;
case RequestMessageTypeEnum.image: //图片消息
HandleImageMessage((RequestImageMessage)bm);
break;
//处理其他消息
case RequestMessageTypeEnum.event: //事件
RequestEventMessage ev=(RequestEventMessage)bm;
switch(ev.Event)
{
case RequestEventTypeEnum.subscribe: //订阅
HandleSubscribeMessage((RequestSubscribeMessage)ev);
break;
case RequestEventTypeEnum.unsubscribe: //取消订阅
HandleUnsubscribeMessage((RequestUnsubscribeMessage)ev);
break;
//处理其他事件
}
break;
default:
break;
}
处理消息
解析消息的细节请参看源代码:http://git.oschina.net/xrwang2/xrwang.weixin.PublicAccount/blob/master/PublicAccount/RequestMessage/RequestMessageHelper.cs
4 被动回复消息
从微信服务器接收到消息(事件)之后,我们可以在5秒之内直接(被动)回复消息;也可以先直接回复空字符串,然后再在48小时内回复客服消息。
先初始化ResponseXxxMessage,然后用ToXml方法得到响应消息内容。
被动回复消息的示例如下:
///
/// 处理微信的POST请求
///
/// 
/// 返回xml响应
private string HandlePost(HttpContext context)
{
RequestMessageHelper helper = new RequestMessageHelper(context.Request);
if (helper.Message != null)
{
ResponseBaseMessage responseMessage = HandleRequestMessage(helper.Message);
return responseMessage.ToXml(helper.EncryptType);
}
else
return string.Empty;
}
///
/// 处理请求消息,返回响应消息
///
/// 返回响应消息
private ResponseBaseMessage HandleRequestMessage(RequestBaseMessage requestMessage)
{
ResponseTextMessage response = new ResponseTextMessage(requestMessage.FromUserName, requestMessage.ToUserName, 
DateTime.Now, string.Format("自动回复,请求内容如下:\r\n{0}", requestMessage));
return response;
}
被动回复消息
5 发送其他消息
除了被动回复消息之外,我们还可以发送客服消息、群发消息、发送模板消息。

原文:http://kunshan.dajiake.com/article/index.php?id=53

转载于:https://www.cnblogs.com/kunshandajiake/p/4334004.html

你可能感兴趣的文章
QTC++监控USB插拔
查看>>
Java生成javadoc
查看>>
ZedGraph控件的使用--属性和例子代码
查看>>
文件管理
查看>>
webpack
查看>>
Atitit.swift 的新特性 以及与java的对比 改进方向attilax 总结
查看>>
Atitit 图像处理 平滑 也称 模糊, 归一化块滤波、高斯滤波、中值滤波、双边滤波)...
查看>>
Android Camera——拍照(转自http://vaero.blog.51cto.com/4350852/779942)
查看>>
Java Web项目移植
查看>>
11月的第一天
查看>>
2011简单总结
查看>>
android的Environment类,记录一下
查看>>
工作流Activiti5流程变量 任务变量 setVariables 跟 setVariablesLocal区别
查看>>
今日笔记:持续集成、面向对象设计方法
查看>>
c语言诊断_断言库函数#include<assert.h>
查看>>
input type="file"获取文件名方法
查看>>
强力上攻后,缓解期结束,MACD死叉的案例
查看>>
Linux文件权限
查看>>
js替换字符串中特殊字符
查看>>
第一单元OO总结
查看>>