当前位置: 代码迷 >> .NET相关 >> .NET微信大众号开发-4.0公众号消息处理
  详细解决方案

.NET微信大众号开发-4.0公众号消息处理

热度:261   发布时间:2016-04-24 02:48:11.0
.NET微信公众号开发-4.0公众号消息处理

一.前言

  微信公众平台的消息处理还是比较完善的,有最基本的文本消息,到图文消息,到图片消息,语音消息,视频消息,音乐消息其基本原理都是一样的,只不过所post的xml数据有所差别,在处理消息之前,我们要认真阅读,官方给我们的文档:http://mp.weixin.qq.com/wiki/14/89b871b5466b19b3efa4ada8e577d45e.html。首先我们从最基本的文本消息处理开始。

<xml><ToUserName><![CDATA[toUser]]></ToUserName><FromUserName><![CDATA[fromUser]]></FromUserName><CreateTime>12345678</CreateTime><MsgType><![CDATA[text]]></MsgType><Content><![CDATA[你好]]></Content></xml>

  我们可以看到这是消息处理的一个最基本的模式,有发送者,接受者,创建时间,类型,内容等等。

首先我们来创建一个消息处理的类,这个类用来捕获,所有的消息请求,根据不同的消息请求类型来处理不同的消息回复。

public class WeiXinService    {        /// <summary>        /// TOKEN        /// </summary>        private const string TOKEN = "finder";        /// <summary>        /// 签名        /// </summary>        private const string SIGNATURE = "signature";        /// <summary>        /// 时间戳        /// </summary>        private const string TIMESTAMP = "timestamp";        /// <summary>        /// 随机数        /// </summary>        private const string NONCE = "nonce";        /// <summary>        /// 随机字符串        /// </summary>        private const string ECHOSTR = "echostr";        /// <summary>        ///         /// </summary>        private HttpRequest Request { get; set; }        /// <summary>        /// 构造函数        /// </summary>        /// <param name="request"></param>        public WeiXinService(HttpRequest request)        {            this.Request = request;        }        /// <summary>        /// 处理请求,产生响应        /// </summary>        /// <returns></returns>        public string Response()        {            string method = Request.HttpMethod.ToUpper();            //验证签名            if (method == "GET")            {                if (CheckSignature())                {                    return Request.QueryString[ECHOSTR];                }                else                {                    return "error";                }            }            //处理消息            if (method == "POST")            {                return ResponseMsg();            }            else            {                return "无法处理";            }        }        /// <summary>        /// 处理请求        /// </summary>        /// <returns></returns>        private string ResponseMsg()        {            string requestXml = CommonWeiXin.ReadRequest(this.Request);            IHandler handler = HandlerFactory.CreateHandler(requestXml);                 if (handler != null)            {                return handler.HandleRequest();            }            return string.Empty;        }        /// <summary>        /// 检查签名        /// </summary>        /// <param name="request"></param>        /// <returns></returns>        private bool CheckSignature()        {            string signature = Request.QueryString[SIGNATURE];            string timestamp = Request.QueryString[TIMESTAMP];            string nonce = Request.QueryString[NONCE];            List<string> list = new List<string>();            list.Add(TOKEN);            list.Add(timestamp);            list.Add(nonce);            //排序            list.Sort();            //拼串            string input = string.Empty;            foreach (var item in list)            {                input += item;            }            //加密            string new_signature = SecurityUtility.SHA1Encrypt(input);            //验证            if (new_signature == signature)            {                return true;            }            else            {                return false;            }        }    }

在来看看我们的首先是如何捕获消息的。首页Default.ashx的代码如下

        public void ProcessRequest(HttpContext context)        {            context.Response.ContentType = "text/html";                        string postString = string.Empty;            if (HttpContext.Current.Request.HttpMethod.ToUpper() == "POST")            {                //由微信服务接收请求,具体处理请求                WeiXinService wxService = new WeiXinService(context.Request);                string responseMsg = wxService.Response();                context.Response.Clear();                context.Response.Charset = "UTF-8";                context.Response.Write(responseMsg);                context.Response.End();            }            else            {                string token = "wei2414201";                if (string.IsNullOrEmpty(token))                {                    return;                }                string echoString = HttpContext.Current.Request.QueryString["echoStr"];                string signature = HttpContext.Current.Request.QueryString["signature"];                string timestamp = HttpContext.Current.Request.QueryString["timestamp"];                string nonce = HttpContext.Current.Request.QueryString["nonce"];                if (!string.IsNullOrEmpty(echoString))                {                    HttpContext.Current.Response.Write(echoString);                    HttpContext.Current.Response.End();                }            }        }

从上面的代码中我们可以看到WeiXinService.cs类中的消息相应至关重要。

        /// <summary>        /// 处理请求        /// </summary>        /// <returns></returns>        private string ResponseMsg()        {            string requestXml = CommonWeiXin.ReadRequest(this.Request);            IHandler handler = HandlerFactory.CreateHandler(requestXml);                 if (handler != null)            {                return handler.HandleRequest();            }            return string.Empty;        }

IHandler是一个消息处理接口,其下面有EventHandler,TextHandler处理类实现这个接口。代码如下

    /// <summary>    /// 处理接口    /// </summary>    public interface IHandler    {        /// <summary>        /// 处理请求        /// </summary>        /// <returns></returns>        string HandleRequest();    }

EventHandler

class EventHandler : IHandler    {        /// <summary>        /// 请求的xml        /// </summary>        private string RequestXml { get; set; }        /// <summary>        /// 构造函数        /// </summary>        /// <param name="requestXml"></param>        public EventHandler(string requestXml)        {            this.RequestXml = requestXml;        }        /// <summary>        /// 处理请求        /// </summary>        /// <returns></returns>        public string HandleRequest()        {            string response = string.Empty;            EventMessage em = EventMessage.LoadFromXml(RequestXml);            if (em.Event.Equals("subscribe", StringComparison.OrdinalIgnoreCase))//用来判断是不是首次关注            {                PicTextMessage tm = new PicTextMessage();//我自己创建的一个图文消息处理类                tm.ToUserName = em.FromUserName;                tm.FromUserName = em.ToUserName;                tm.CreateTime = CommonWeiXin.GetNowTime();                response = tm.GenerateContent();            }            return response;        }    }

TextHandler

    /// <summary>    /// 文本信息处理类    /// </summary>    public class TextHandler : IHandler    {        string openid { get; set; }        string access_token { get; set; }        /// <summary>        /// 请求的XML        /// </summary>        private string RequestXml { get; set; }        /// <summary>        /// 构造函数        /// </summary>        /// <param name="requestXml">请求的xml</param>        public TextHandler(string requestXml)        {            this.RequestXml = requestXml;        }        /// <summary>        /// 处理请求        /// </summary>        /// <returns></returns>        public string HandleRequest()        {            string response = string.Empty;            TextMessage tm = TextMessage.LoadFromXml(RequestXml);            string content = tm.Content.Trim();            if (string.IsNullOrEmpty(content))            {                response = "您什么都没输入,没法帮您啊。";            }            else            {                    string username = System.Configuration.ConfigurationManager.AppSettings["weixinid"].ToString();                    AccessToken token = AccessToken.Get(username);                    access_token = token.access_token;                    openid = tm.FromUserName;                    response = HandleOther(content);                            }            tm.Content = response;            //进行发送者、接收者转换            string temp = tm.ToUserName;            tm.ToUserName = tm.FromUserName;            tm.FromUserName = temp;            response = tm.GenerateContent();            return response;        }        /// <summary>        /// 处理其他消息        /// </summary>        /// <param name="tm"></param>        /// <returns></returns>        private string HandleOther(string requestContent)        {            string response = string.Empty;            if (requestContent.Contains("你好") || requestContent.Contains("您好"))            {                response = "您也好~";            }else if (requestContent.Contains("openid") || requestContent.Contains("id") || requestContent.Contains("ID"))//用来匹配用户输入的关键字            {                response = "你的Openid: "+openid;            }            else if (requestContent.Contains("token") || requestContent.Contains("access_token"))            {                response = "你的access_token: " + access_token;            }else             {                response = "试试其他关键字吧。";            }            return response;        }    }

HandlerFactory

    /// <summary>    /// 处理器工厂类    /// </summary>    public class HandlerFactory    {        /// <summary>        /// 创建处理器        /// </summary>        /// <param name="requestXml">请求的xml</param>        /// <returns>IHandler对象</returns>        public static IHandler CreateHandler(string requestXml)        {            IHandler handler = null;            if (!string.IsNullOrEmpty(requestXml))            {                //解析数据                XmlDocument doc = new System.Xml.XmlDocument();                doc.LoadXml(requestXml);                XmlNode node = doc.SelectSingleNode("/xml/MsgType");                if (node != null)                {                    XmlCDataSection section = node.FirstChild as XmlCDataSection;                    if (section != null)                    {                        string msgType = section.Value;                        switch (msgType)                        {                            case "text":                                handler = new TextHandler(requestXml);                                break;                            case "event":                                handler = new EventHandler(requestXml);                                break;                        }                    }                }            }            return handler;        }    }

 在这里基本的一些类已经完成了,现在我们来完成,关注我们的微信公众号,我们就发送一条图文消息,同时输入我们的一些关键字,返回一些消息,比如输入id返回用户的openid等等。

二.PicTextMessage

public class PicTextMessage : Message    {        /// <summary>        /// 模板静态字段        /// </summary>        private static string m_Template;        /// <summary>        /// 默认构造函数        /// </summary>        public PicTextMessage()        {            this.MsgType = "news";        }        /// <summary>        /// 从xml数据加载文本消息        /// </summary>        /// <param name="xml"></param>        public static PicTextMessage LoadFromXml(string xml)        {            PicTextMessage tm = null;            if (!string.IsNullOrEmpty(xml))            {                XElement element = XElement.Parse(xml);                if (element != null)                {                    tm = new PicTextMessage();                    tm.FromUserName = element.Element(CommonWeiXin.FROM_USERNAME).Value;                    tm.ToUserName = element.Element(CommonWeiXin.TO_USERNAME).Value;                    tm.CreateTime = element.Element(CommonWeiXin.CREATE_TIME).Value;                }            }            return tm;        }        /// <summary>        /// 模板        /// </summary>        public override string Template        {            get            {                if (string.IsNullOrEmpty(m_Template))                {                    LoadTemplate();                }                return m_Template;            }        }        /// <summary>        /// 生成内容        /// </summary>        /// <returns></returns>        public override string GenerateContent()        {            this.CreateTime = CommonWeiXin.GetNowTime();            string str= string.Format(this.Template, this.ToUserName, this.FromUserName, this.CreateTime);            return str;        }        /// <summary>        /// 加载模板        /// </summary>        private static void LoadTemplate()        {            m_Template= @"<xml>                            <ToUserName><![CDATA[{0}]]></ToUserName>                            <FromUserName><![CDATA[{1}]]></FromUserName>                            <CreateTime>{2}</CreateTime>                            <MsgType><![CDATA[news]]></MsgType>                            <ArticleCount>1</ArticleCount>                            <Articles>                                <item>                                <Title><![CDATA[有位停车欢迎你!]]></Title>                                 <Description><![CDATA[如有问题请致电400-6238-136或直接在微信留言,我们将第一时间为您服务!]]></Description>                                <PicUrl><![CDATA[http://www.baidu.com/youwei.jpg]]></PicUrl>                                <Url><![CDATA[http://www.baidu.com]]></Url>                                </item>                            </Articles>                        </xml> ";        }    }

最后我们的效果如下所示;

本人能力有限,希望大家多多包涵.

三.微信公众号开发系列导航

1.0初始微信公众号

2.0创建自定义菜单

3.0查询自定义菜单

4.0公众号消息处理

5.0微信支付

6.0模板消息

1楼You最温暖的港湾
不错。
Re: 枫伶忆
@You最温暖的港湾,相互学习,谢谢支持
  相关解决方案