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

项目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》。

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),我觉得这里以后还是会做大文章的。

四:微信测试号效果展示

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

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

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

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

微信开发系列----02:实现POST请求响应的更多相关文章

  1. 《C#微信开发系列(4)-接收 / 返回文本消息》

    4.0接收 / 返回文本消息 ①接收/返回文本消息原理说明 当普通微信用户向公众账号发消息时,微信服务器将POST消息的XML数据包到开发者填写的URL上,着手开发之前先行阅读微信公众平台接收普通消息 ...

  2. 《C#微信开发系列(3)-获取接口调用凭据》

    3.0获取接口调用凭据 ①接口说明 access_token是公众号的全局唯一票据,公众号调用各接口时都需使用access_token.开发者需要进行妥善保存.access_token的存储至少要保留 ...

  3. 《C#微信开发系列(2)-自定义菜单管理》

    2.0自定义菜单管理 ①接口说明 微信服务号聊天窗口下面的菜单项(有的公众号有启用有的则没有),这个可以在编辑模式简单配置,也可以在开发模式代码配置.微信公众平台开发者文档:微信公众号开发平台创建自定 ...

  4. 《C#微信开发系列(1)-启用开发者模式》

    1.0启用开发者模式 ①填写服务器配置 启用开发模式需要先成为开发者,而且编辑模式和开发模式只能选择一个(进入微信公众平台=>开发=>基本配置)就可以看到以下的界面: 点击修改配置,会出现 ...

  5. Force.com微信开发系列(五)自定义菜单进阶及语音识别

    在上文里我们介绍了如何通过Force.com平台里为微信账号添加自定义菜单,本文里我们将进一步介绍如何查询菜单以及删除菜单的相关知识,最后会介绍微信平台如何进行语音识别的相关技术. 查询菜单 与创建菜 ...

  6. 《C#微信开发系列(Top)-微信开发完整学习路线》

    年前就答应要将微信开发的学习路线整理给到大家,但是因为年后回来这段时间学校还有公司那边有很多事情需要兼顾,所以没能及时更新文章.今天特地花时间整理了下,话不多说,上图,希望对大家的学习有所帮助哈. 如 ...

  7. 微信开发系列——微信订阅号前端开发利器:WeUI

    前言:年前的两个星期,学习了下微信公众号的开发.后端基本能够基于盛派的第三方sdk能搞定大部分事宜.剩下的就是前端了,关于手机端的浏览器的兼容性,一直是博主的一块心病,因为博主一直专注于bootstr ...

  8. Force.com微信开发系列(四)申请Access Token及自定义菜单之创建菜单

    在微信接口开发中,许多服务的使用都离不开Access Token,Access Token相当于打开这些服务的钥匙,正常情况下会在7200秒内失效,重复获取将导致上次获取的Token失效,本文将首先介 ...

  9. Force.com微信开发系列(七)OAuth2.0网页授权

    OAuth是一个开放协议,允许用户让第三方应用以安全且标准的方式获取该用户在某一网站上存储的私密资源(如用户个人信息.照片.视频.联系人列表),而无须将用户名和密码提供给第三方应用.本文将详细介绍OA ...

随机推荐

  1. AIX 文件 打包 与 压缩 tar gzip compress 的使用

    今天在Aix用tar -cvf 备份,打成tar包,占有硬盘空间过大,没有压缩比, 尝试使用tar -zcvf  linux系统下可以用-z 命令 (z 用gzip来压缩/解压缩文件,加上该选项后可以 ...

  2. 必应词典UWP版-开发小结

    摘要 必应词典UWP版已经上线2周了!相信有不少用户都已经体验过了吧!得益于Win10全新.强大的API,新版词典在性能上.UI体验上都有了大幅的提升,今天,小编就为大家讲讲必应词典UWP开发的故事. ...

  3. openwrt-智能路由器hack技术(2)---"网路信息监控和窃取"

    openwrt-智能路由器hack技术(2)---"网路信息监控和窃取" 1   导读 PS:之前写的一个文章,现在发现结构内容排版不是太好,导致阅读体验太差,影响传播和SEO,所 ...

  4. Winform启动隐藏,WebBrowser交互JS

    一.启动隐藏 Winform比较奇怪,Load的时候设置Visiable=false,无效.webBrowser_DocumentCompleted之后调用hide隐藏了窗体,但是在notifyIco ...

  5. python 对象

    python 对象 在python中,对象就是为C中的结构体在堆上申请的一块内存,一般来说,对象是不能被静态初始化的,并且不能再栈空间上生存.本文主要对Python的基本数据类型做简单的介绍. PyO ...

  6. [安卓] 19、一个蓝牙4.0安卓DEMO

    一.工程结构&概述 整个应用包含两个按钮,一个是搜索所有蓝牙设备,另一个是连接所有蓝牙设备~ 下面是整个工程的文件结构: 二.代码业务流程跟踪 2.1.两个按钮 下面讲讲该工程里的主要跳转流程 ...

  7. 可拖动的DIV

    在做WEB UI设计的时候,拖动某个HTML元素已经成为一种不能忽视的用户界面模式,比较典型的应用例子就是Dialog,一个元素是怎么实现拖动的呢?其实原理非常简单,要想实现首先得了解几个基本知识. ...

  8. splice slice

    array的方法中,有这么两个方法, 很久之前接触flex的时候就知道了. 可是总是记不太清. splice() 方法向/从数组中添加/删除项目,然后返回被删除的项目 slice() 方法可从已有的数 ...

  9. 启发式算法(Heuristic Algorithm)

    背景: 李航的<统计学习方法>一书中提到:决策树算法通常采用启发式算法,故了解之 问题解答: 时间有限,这里也只是将算法和启发式算法的区别和简单发展摘录如下: 一.算法和启发式方法之间的差 ...

  10. Thrift架构~windows下安装和Hello World及编码引起的错误

    最近开始正式接触Thrift架构,很牛B的技术,它被apache收纳了,属于开源中的一员,呵呵. 概念: Thrift源于大名鼎鼎的facebook之手,在2007年facebook提交Apache基 ...