『QQ:1353814576』

微信公众平台C#开发系列(十):微信公众号推送消息事件-接收普通消息


服务器接收微信公众号推送的消息和事件的内容读取和解析

当普通微信用户向公众账号发消息时,微信服务器将POST消息的XML数据包到开发者填写的URL上。需要开发者服务器对xml数据包进行解析然后回复微信客户端应答操作的指令。

官方文档地址:

https://developers.weixin.qq.com/doc/offiaccount/Message_Management/Receiving_standard_messages.html#

(公众号如何接入开发服务器请参考下方链接)

微信公众平台C#开发系列(三):公众平台接入

开始动手敲代码

公共部分 因为接口有部分属性字段是通用的 所以首先定义一个消息公共类 WeiXinXmlMessage 用于类继承

namespace YuanTK.WeiXin.WeiXinPushWrapper
{

    [Serializable]
    /// <summary>
    /// 微信推送消息的公共参数类
    /// </summary>
    public class WeiXinXmlMessage
    {
        /// <summary>
        /// 消息类型
        /// </summary>
        public enum MessageType
        {
            /// <summary>
            /// 文本消息
            /// </summary>
            text,
            /// <summary>
            /// 图片
            /// </summary>
            image,
            /// <summary>
            /// 语音消息
            /// </summary>
            voice,
            /// <summary>
            /// 视频消息
            /// </summary>
            video,
            /// <summary>
            /// 短视频消息
            /// </summary>
            shortvideo,
            /// <summary>
            /// 定位消息
            /// </summary>
            location,
            /// <summary>
            /// 超链接跳转事件
            /// </summary>
            @link,
            /// <summary>
            /// 菜单点击事件
            /// </summary>
            @event
        }
        [JsonProperty(Order = -100)]
        /// <summary>
        /// 开发者 微信号
        /// </summary>
        public string ToUserName{get;set; }

        [JsonProperty(Order = -99)]
        /// <summary>
        /// 发送方帐号(一个OpenID)
        /// </summary>
        public string FromUserName { get; set; }

        [JsonProperty(Order = -98)]
        /// <summary>
        /// 消息创建时间 (整型)
        /// </summary>
        public string CreateTime { get; set; }

        [JsonProperty(Order = -98)]
        [JsonConverter(typeof(StringEnumConverter))]
        /// <summary>
        /// 消息类型,event
        /// </summary>
        public MessageType MsgType { get; set; }

        /// <summary>
        /// 解析微信消息
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="xmlString"></param>
        /// <returns></returns>
        public static T Load<T>(string xmlString)where T: WeiXinXmlMessage
        {
            ///正则表达式 去除xml中 CDATA属性标签
            xmlString = xmlString.Replace("<![CDATA[", "").Replace("]]>", "");
            ///加载xml
            XmlDocument doc = new XmlDocument();
            doc.LoadXml(xmlString);
            ///xml转换成json
            string jsonString = JsonConvert.SerializeXmlNode(doc);
            ///反序列化json
            XmlRoot<T> xmlroot = JsonConvert.DeserializeObject<XmlRoot<T>>(jsonString);
            ///返回根节点信息
            return xmlroot.xml;
        }

        /// <summary>
        /// 序列化为xml字符串
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        public static string SerializeXml(object model)
        {
            ///按照接口文档字段进行格式封装
            object xmlModel = new { xml = model };
            string jsonString = JsonConvert.SerializeObject(xmlModel);
            XmlDocument xml = JsonConvert.DeserializeXmlNode(jsonString);
            return xml.InnerXml;
        }

        /// <summary>
        /// 根节点信息
        /// </summary>
        /// <typeparam name="T"></typeparam>
        class XmlRoot<T> where T : WeiXinXmlMessage
        {
            /// <summary>
            /// 根节点
            /// </summary>
            public T xml { get; set; }
        }
    }
}

[TOC]

2.接收普通消息

定义文本消息类 TextMessageResponse 继承自 WeiXinXmlMessage

namespace YuanTK.WeiXin.WeiXinPushWrapper
{
    /// <summary>
    /// 文本消息
    /// </summary>
    public class TextMessageResponse : WeiXinXmlMessage
    {
        /// <summary>
        /// 文本消息内容
        /// </summary>
        public string Content { get; set; }
        /// <summary>
        /// 消息id,64位整型
        /// </summary>
        public string MsgId { get; set; }
    }
}

调用方式以官方的例子xml字符串为例

string xml = @"<xml><ToUserName><![CDATA[gh_e136c6e50636]]></ToUserName>
<FromUserName><![CDATA[oMgHVjngRipVsoxg6TuX3vz6glDg]]></FromUserName>
<CreateTime>1408090502</CreateTime>
<MsgType><![CDATA[event]]></MsgType>
<Event><![CDATA[scancode_push]]></Event>
<EventKey><![CDATA[6]]></EventKey>
</xml>";
TextMessageResponse response = WeiXinXmlMessage.Load<TextMessageResponse>(xml);

3.接收图片消息

定义图片消息类 ImageMessageResponse 继承自 WeiXinXmlMessage


namespace YuanTK.WeiXin.WeiXinPushWrapper
{
    /// <summary>
    /// 图片消息
    /// </summary>
    public class ImageMessageResponse : WeiXinXmlMessage
    {
        /// <summary>
        /// 图片链接(由系统生成)
        /// </summary>
        public string PicUrl { get; set; }
        /// <summary>
        ///  图片消息媒体id,可以调用获取临时素材接口拉取数据。
        /// </summary>
        public string MediaId { get; set; }
        /// <summary>
        /// 消息id,64位整型
        /// </summary>
        public string MsgId { get; set; }
    }
}

调用方式如上(调用套路看懂了的后面的就无需再看了 基本就是接收类变一变)

ImageMessageResponse response = WeiXinXmlMessage.Load<ImageMessageResponse>(xml);

4.接收语音消息

定义语音消息类 VoiceMessageResponse 继承自 WeiXinXmlMessage


namespace YuanTK.WeiXin.WeiXinPushWrapper
{
    /// <summary>
    /// 语音消息
    /// </summary>
    public class VoiceMessageResponse : WeiXinXmlMessage
    {
        /// <summary>
        /// 语音格式,如amr,speex等
        /// </summary>
        public string Format { get; set; }
        /// <summary>
        ///  图片消息媒体id,可以调用获取临时素材接口拉取数据。
        /// </summary>
        public string MediaId { get; set; }
        /// <summary>
        /// 消息id,64位整型
        /// </summary>
        public string MsgId { get; set; }
    }
}

调用方式如上

VoiceMessageResponse response = WeiXinXmlMessage.Load<VoiceMessageResponse>(xml);

5.接收视频(小视频 二者MsgType区分)消息

定义视频消息类 VideoMessageResponse 继承自 WeiXinXmlMessage

namespace YuanTK.WeiXin.WeiXinPushWrapper
{
    /// <summary>
    /// 视频消息
    /// </summary>
    public class VideoMessageResponse : WeiXinXmlMessage
    {
        /// <summary>
        /// 视频消息缩略图的媒体id,可以调用多媒体文件下载接口拉取数据。
        /// </summary>
        public string ThumbMediaId { get; set; }
        /// <summary>
        ///  视频消息媒体id,可以调用获取临时素材接口拉取数据。
        /// </summary>
        public string MediaId { get; set; }
        /// <summary>
        /// 消息id,64位整型
        /// </summary>
        public string MsgId { get; set; }
    }
}

调用方式如上

VideoMessageResponse response = WeiXinXmlMessage.Load<VideoMessageResponse>(xml);

6.地理位置消息

定义视频消息类 LocationMessageResponse 继承自 WeiXinXmlMessage


namespace YuanTK.WeiXin.WeiXinPushWrapper
{

    /// <summary>
    /// 地理位置消息
    /// </summary>
    public class LocationMessageResponse : WeiXinXmlMessage
    {
        /// <summary>
        /// 地理位置纬度
        /// </summary>
        public string Location_X { get; set; }

        /// <summary>
        /// 地理位置经度
        /// </summary>

        public string Location_Y { get; set; }

        /// <summary>
        /// 地图缩放大小
        /// </summary>
        public string Scale { get; set; }

        /// <summary>
        /// 地理位置信息
        /// </summary>
        public string Label { get; set; }

        /// <summary>
        /// 消息id,64位整型
        /// </summary>
        public string MsgId { get; set; }
    }
}

调用方式如上

LocationMessageResponse response = WeiXinXmlMessage.Load<LocationMessageResponse>(xml);

7.接收链接消息

定义链接消息类 LinkMessageResponse 继承自 WeiXinXmlMessage



namespace YuanTK.WeiXin.WeiXinPushWrapper
{

    /// <summary>
    /// 链接消息
    /// </summary>
    public class LinkMessageResponse : WeiXinXmlMessage
    {
        /// <summary>
        /// 消息标题
        /// </summary>
        public string Title { get; set; }

        /// <summary>
        /// 消息描述
        /// </summary>

        public string Description { get; set; }

        /// <summary>
        /// 消息链接
        /// </summary>
        public string Url { get; set; }

        /// <summary>
        /// 消息id,64位整型
        /// </summary>
        public string MsgId { get; set; }
    }
}

调用方式如上

LinkMessageResponse response = WeiXinXmlMessage.Load<LinkMessageResponse>(xml);

微信公众号凭证access_token如何获取?