.NET微信公衆號開發-4.0公衆號消息處理

一.前言

  微信公衆平臺的消息處理仍是比較完善的,有最基本的文本消息,到圖文消息,到圖片消息,語音消息,視頻消息,音樂消息其基本原理都是同樣的,只不過所post的xml數據有所差異,在處理消息以前,咱們要認真閱讀,官方給咱們的文檔:http://mp.weixin.qq.com/wiki/14/89b871b5466b19b3efa4ada8e577d45e.html。首先咱們從最基本的文本消息處理開始。html

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

  咱們能夠看到這是消息處理的一個最基本的模式,有發送者,接受者,建立時間,類型,內容等等。node

首先咱們來建立一個消息處理的類,這個類用來捕獲,全部的消息請求,根據不一樣的消息請求類型來處理不一樣的消息回覆。微信

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類中的消息相應相當重要。ide

        /// <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();
    }

EventHandlerpost

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;
        }
    }

HandlerFactorythis

    /// <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模板消息

相關文章
相關標籤/搜索