微信开发系列---02:实现POST请求响应

继续昨天的,现在我们的微信测试成功了,可以开发实现微信的各种功能,今天主要实现微信的简单交互,比如发送语音,图片,文本等请求,网站服务器发送对应的响应。
项目GitHub地址: https://github.com/Andyahui/xgyxsh_WeiXin

一:微信XML的POST请求处理

昨天我们已经成为了开发者,说明get请求时可以到底,且是得到了相应的处理,下面是我们通过浏览器我们配置的URL浏览到的。


有理想的人了不起

我们可以发现在get请求中设置的返回值在这里出现了,说明我们的测试是成功的。下面我们需要设置POST请求对应的Action。
注意:由于我们微信和网站服务器的每一次交互都是通过POST请求来得到自己想要的东西,我们就必须为传输进行加密。

    /// <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》。 从上到下分析。发现它是继承自MessageHandler但是它后面还有个CustomMessageContext,此时对于MessageHandler有了重新的认识,这货原来是个泛型的抽象类,我们需要往里面填写个类型,查看官方说明说这个CustomMessageContext是个自定义的上下文类,到底是什么了,我也没仔细研究,看官方的介绍吧(WiKi)。接着下面是个CTOR,主要是实例化的时候使用<POST请求的时候使用过>,注意里面的参数,一个是请求流inputSrream,一个是微信服务器发送的数据类PostModel。在接着就是我们实现的方法了,第一个是DefaultResponseMessage方法,这个是必须实现的。因为它是处理微信请求来没有响应的数据,默认给微信服务器发送消息的。最后到了文本处理了,这里override了OnTextRequest方法,从而可以对应响应用户的文本信息请求。我们要是需要实现别的处理,比如图片,语音,地理位置等,分别重写别的方法,返回对应的消息类型就可以实现。

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

三:自定义上下文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,我觉得这里以后还是会做大文章的。

四:微信测试号效果展示

此时我们大体的底层框架就搭建成功了,我们发布部署到服务器上面就可以看到文本处理的响应了。

有梦想的人了不起

这是微信的二维码可以关注下,可以实现简单的互动。


有梦想的人了不起

终于成功了,其中遇到了很多问题,自己根本就想不到,还是要多多阅读别人写的代码,这样自己才会进步的很快。

---------------------期待下一篇吧,将实现微信基本的请求处理----------

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,064评论 5 466
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,606评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,011评论 0 328
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,550评论 1 269
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,465评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 47,919评论 1 275
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,428评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,075评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,208评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,185评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,191评论 1 328
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,914评论 3 316
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,482评论 3 302
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,585评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,825评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,194评论 2 344
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,703评论 2 339

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,555评论 18 139
  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 171,234评论 25 707
  • AFHTTPRequestOperationManager 网络传输协议UDP、TCP、Http、Socket、X...
    Carden阅读 4,308评论 0 12
  • 红灯,司机师傅一个急刹车,原本以为可以在红灯亮起前冲过去的,似乎还压了线。对于出租车行业,可能时间真的就是金钱吧!...
    九丑_阅读 294评论 2 1
  • 吾性自足,不假外求。人人心中自有良知,良知无所不能,可以解决任何问题,不需要任何外来帮助。 理学大师张载:为天地立...
    婷婷爱瑜伽阅读 308评论 0 0