.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> ";

        }

    }

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

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

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

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

1.0初始微信公众号

2.0创建自定义菜单

3.0查询自定义菜单

4.0公众号消息处理

5.0微信支付

6.0模板消息

你可能感兴趣的:(微信公众号)