核心原理
用户给公众号发消息 → 微信服务器POST XML数据推送至你配置的回调URL(WeiXinTokenApi.aspx)。
同一个页面,要同时处理两种请求:
GET:微信后台配置时的Token签名校验(验证服务器地址)POST:用户发消息时,微信推送XML消息数据
页面入口代码 WeiXinTokenApi.aspx.cs
if ("POST" == Request.RequestType)
{
// POST:接收微信推送消息
ResponseMsg();
}
else
{
// GET:微信服务器Token校验
CheckSignature();
}
Code language: JavaScript (javascript)
ResponseMsg() 接收消息方法
private void ResponseMsg()
{
string postString = string.Empty;
using (Stream stream = HttpContext.Current.Request.InputStream)
{
Byte[] postBytes = new Byte[stream.Length];
stream.Read(postBytes, 0, (Int32)stream.Length);
// 微信推送XML编码:GBK
postString = Encoding.GetEncoding("GBK").GetString(postBytes);
}
// 加载XML文档
XmlDocument xmldoc = new XmlDocument();
xmldoc.Load(new MemoryStream(Encoding.GetEncoding("GB2312").GetBytes(postString)));
// 读取消息类型 MsgType
XmlNode MsgType = xmldoc.SelectSingleNode("/xml/MsgType");
if(MsgType.InnerText == "text")
{
// 文本消息,在这里写业务逻辑:保存数据库、自动回复等
}
// 处理完成后,返回响应XML给微信服务器
string responseContent = ReturnMessage(postString);
Response.Write(responseContent);
Response.End();
}
Code language: PHP (php)
CheckSignature() 校验方法
微信在配置回调地址时GET请求进来,校验签名,返回随机字符串
echostr。
流程拆解
- 用户发消息 → 微信服务器 POST XML 到你的
WeiXinTokenApi.aspx - 读取
Request.InputStream获取原始报文,编码GBK - 用
XmlDocument解析XML - 读取节点
/xml/MsgType判断消息类型:text文本消息,还有image、voice等类型 - 业务处理:存入缓存/数据库、自动回复
- 拼接回复XML字符串,
Response.Write返回给微信服务器
XML消息示例(用户发文本消息)
<xml>
<ToUserName><![CDATA[公众号ID]]></ToUserName>
<FromUserName><![CDATA[用户OpenId]]></FromUserName>
<CreateTime>1726789012</CreateTime>
<MsgType><![CDATA[text]]></MsgType>
<Content><![CDATA[你好]]></Content>
<MsgId>2481234567890123</MsgId>
</xml>
Code language: HTML, XML (xml)
关键点
- 同一个URL同时支持GET和POST,通过
Request.RequestType区分 - 微信推送的消息XML编码是 GBK/GB2312,读取流的时候编码不能错,否则中文乱码
- 必须给微信服务器返回响应XML,微信才认为消息推送成功;超时会重试推送
- 本课程示例:把收到的XML放到缓存,直接访问页面就能查看收到的消息内容
配套 ReturnMessage 函数(构造回复xml)
private string ReturnMessage(string postXml)
{
XmlDocument doc = new XmlDocument();
doc.LoadXml(postXml);
string fromUser = doc.SelectSingleNode("//FromUserName").InnerText;
string toUser = doc.SelectSingleNode("//ToUserName").InnerText;
string replyContent = "收到消息啦";
// 组装回复文本消息xml
string replyXml = $"<xml><ToUserName><![CDATA[{fromUser}]]></ToUserName><FromUserName><![CDATA[{toUser}]]></FromUserName><CreateTime>{DateTimeOffset.UtcNow.ToUnixTimeSeconds()}</CreateTime><MsgType><![CDATA[text]]></MsgType><Content><![CDATA[{replyContent}]]></Content></xml>";
return replyXml;
}
Code language: HTML, XML (xml)
Previous: 查询微信自定义菜单接口
Next: 【客服】自动回复完整代码