微信開發系列----02:實現POST請求響應

    繼續昨天的,如今咱們的微信測試成功了,能夠開發實現微信的各類功能,今天主要實現微信的簡單交互,好比發送語音,圖片,文本等請求,網站服務器發送對應的響應。 html

項目GitHub地址:  https://github.com/Andyahui/xgyxsh_WeiXingit

一:微信XML的POST請求處理github

    昨天咱們已經成爲了開發者,說明get請求時能夠到底,且是獲得了相應的處理,下面是咱們經過瀏覽器咱們配置的URL瀏覽到的。算法

image

咱們能夠發如今get請求中設置的返回值在這裏出現了,說明咱們的測試是成功的。下面咱們須要設置POST請求對應的Action。sql

  注意:因爲咱們微信和網站服務器的每一次交互都是經過POST請求來獲得本身想要的東西,咱們就必須爲傳輸進行加密。api

        /// <summary>
        /// 用戶發送消息後,微信平臺自動Post一個請求到這裏,並等待響應XML。
        /// PS:此方法爲簡化方法,效果與OldPost一致。
        /// v0.8以後的版本能夠結合Senparc.Weixin.MP.MvcExtension擴展包,使用WeixinResult,見MiniPost方法。
        /// </summary>
        [HttpPost]
        [ActionName("Index")]
        public ActionResult Post(PostModel postModel)
        {
            postModel.Token = Token;
            // postModel.EncodingAESKey = "";          //根據本身後臺的設置保持一致
            // postModel.AppId = AppId;                       //根據本身後臺的設置保持一致  
            //驗證數字簽名
            if (!CheckSignature.Check(postModel.Signature, postModel.Timestamp, postModel.Nonce, Token))
            {
                //??? 這裏有問題,要是不註釋的話,就會在這裏出錯,也就是數字簽名有問題。
                //return Content("參數錯誤!");
            }

            //  1:自定義MessageHandler,對微信請求的詳細判斷操做都在這裏面。  實例化了一個類
            var messageHandler = new CustomMessageHandle(Request.InputStream, postModel);   //接收消息

            //  2:執行微信處理過程----執行完這裏以後ResponseMessage纔會有值。
            messageHandler.Execute();            

            //  3:return new FixWeixinBugWeixinResult(messageHandler); 這個有換行的問題。           
            //return new FixWeixinBugWeixinResult(messageHandler.ToString());

            //  3:注意第三個----爲了解決官方微信5.0軟件換行bug暫時添加的方法,平時用下面一個方法便可
            return new WeixinResult(messageHandler);                 //v0.8+
        } 

   咱們能夠清楚的看到上面的每一行的意思,這裏我有個疑問,驗證數字簽名的裏面要是不註釋if判斷裏面的就直接顯示「參數錯誤」不會繼續執行下面的操做,可是官網博客裏面沒有註釋,不知道爲何??(求大神解答。)瀏覽器

上面主要有三步:服務器

   先是實例化了CustomMessageHandle對象,而且傳遞了對應的參數,經過對應的CTOR進行了初始化,接着調用它的Execute()方法,最後經過實例化WeixinResult來返回對應的CustomMessageHandle對象,此時對象中就包含了咱們網站後臺的邏輯處理方法。微信

<CustomMessageHandle主要是繼承了MessageHandle抽象類,是咱們自定義的>微信開發

   這就是咱們POST請求對於的處理,每一次微信服務器轉發的xml信息都會利用POST請求形式再次轉發到這裏,咱們進行處理。

二:瞭解MessageHandler

     要完成微信開發,SDK中關鍵類就須要瞭解,下面就簡單說下MessageHandler;

MessageHandler是SDK處理消息的核心,主要對於POST請求,進行對應的處理。還能夠進行邏輯判斷,說白了就是咱們全部的業務邏輯都是在這個類下面進行的。<消息和事件>。這是一個抽象類,咱們須要經過繼承從新實現它。下面是具體的實現。《這裏是對應官方的解釋WiKi》。

namespace XGY_WeiXin.WeiXinHelper
{
    public class CustomMessageHandle : MessageHandler<CustomMessageContext>
    {
        //PostModel:表示的都是從微信服務器裏面獲得的值,時間戳,字符串等。(WeiXinController中使用過)
        //構造函數的inputStream用於接收來自微信服務器的請求流(若是須要在外部處理,這裏也能夠傳入XDocument)。
        public CustomMessageHandle(Stream inputSrream,PostModel postModel):base(inputSrream,postModel)
        {            
        }
        /// <summary>
        /// 必須實現抽象的類------做用:用於放回一條信息,當沒有對應類型的微信消息沒有被代碼處理,那麼默認會執行返回這裏的結果。
        /// </summary>
        /// <param name="requestMessage">請求消息</param>
        /// <returns></returns>
    public override IResponseMessageBase DefaultResponseMessage(IRequestMessageBase requestMessage)
    {
        //CreateResponseMessage<T>  這裏是建立一個放回的對象,表明不一樣的類型,
        var responseMessage = base.CreateResponseMessage<ResponseMessageText>();//ResponseMessageText能夠更換爲別的類型
        responseMessage.Content = "這條消息來自DefaultResponseMessage。";
        return responseMessage;
    }
         /// <summary>
        ///1: 處理用戶發送過來的文字消息。重寫OnTextRequest方法。
       /// --------(總結:)方法裏面能夠自由發揮,讀取DB,判斷關鍵字,甚至返回不一樣的ResponseMessageXX類型(只要最終的類型都是在IResponseMessageBase接口下的便可)。
        /// </summary>
        /// <param name="requestMessage">請求消息</param>
        /// <returns></returns>
        public override IResponseMessageBase OnTextRequest(RequestMessageText requestMessage)
        {
            //CreateResponseMessage<類型>根據當前的RequestMessage建立指定類型的ResponseMessage;建立相應消息.
            var responseMessage = base.CreateResponseMessage<ResponseMessageText>();
            responseMessage.Content = "您的OpenID是:" + requestMessage.FromUserName + "。\r\t您發送了文字信息:" +
                                      requestMessage.Content;
            return responseMessage;
        }
    }
}

  從上到下分析。發現它是繼承自MessageHandler可是它後面還有個CustomMessageContext,此時對於MessageHandler有了從新的認識,這貨原來是個泛型的抽象類,咱們須要往裏面填寫個類型,查看官方說明說這個CustomMessageContext是個自定義的上下文類,究竟是什麼了,我也沒仔細研究,看官方的介紹吧(WiKi)。接着下面是個CTOR,主要是實例化的時候使用<POST請求的時候使用過>,注意裏面的參數,一個是請求流inputSrream,一個是微信服務器發送的數據類PostModel。在接着就是咱們實現的方法了,第一個是DefaultResponseMessage方法,這個是必須實現的。由於它是處理微信請求來沒有響應的數據,默認給微信服務器發送消息的。最後到了文本處理了,這裏override了OnTextRequest方法,從而能夠對應響應用戶的文本信息請求。咱們要是須要實現別的處理,好比圖片,語音,地理位置等,分別重寫別的方法,返回對應的消息類型就能夠實現。

三:自定義上下文CustomMessageContext

下面是自定義上下文類CustomMessageContext,主要是繼承自MessageContext<IRequestMessageBase,IResponseMessageBase>來實現對於的功能。

    /// <summary>
    /// 自定義的上下文類---->處理單個用戶的對話狀態。
    /// </summary>
    public class CustomMessageContext : MessageContext<IRequestMessageBase,IResponseMessageBase>
    {
        public CustomMessageContext()
        {
            base.MessageContextRemoved+=CustomMessageContext_MessageContextRemoved;
        }
        /// <summary>
        /// 當上下文過時,被移除的時候觸發的時間
        /// </summary>
        private void CustomMessageContext_MessageContextRemoved(object sender, Senparc.Weixin.Context.WeixinContextRemovedEventArgs<IRequestMessageBase, IResponseMessageBase> e)
        {
            /* 注意,這個事件不是實時觸發的(固然你也能夠專門寫一個線程監控)
            * 爲了提升效率,根據WeixinContext中的算法,這裏的過時消息會在過時後下一條請求執行以前被清除
            */
            var messageContext = e.MessageContext as CustomMessageContext;
            if (messageContext==null)
            {
                //若是是正常的調用,messageContext不會爲null
                return ;                 
            }
            //TODO:這裏根據須要執行消息過時時候的邏輯,下面的代碼僅供參考
            //Log.InfoFormat("{0}的消息上下文已過時",e.OpenId);
            //api.SendMessage(e.OpenId, "因爲長時間未搭理客服,您的客服狀態已退出!");
        }
    }

   解釋參考官方給的解釋,版本升級了(WiKi),我以爲這裏之後仍是會作大文章的。

四:微信測試號效果展現

   此時咱們大致的底層框架就搭建成功了,咱們發佈部署到服務器上面就能夠看到文本處理的響應了。

image

這是微信的二維碼能夠關注下,能夠實現簡單的互動。

image

  終於成功了,其中遇到了不少問題,本身根本就想不到,仍是要多多閱讀別人寫的代碼,這樣本身才會進步的很快。

---------------------期待下一篇吧,將實現微信基本的請求處理----------------

相關文章
相關標籤/搜索