本书以深度剖析Senparc.Weixin SDK框架的设计思想和使用方法为主干,全面介绍了开发微信公众号(包含了订阅号、服务号和小程序)所需的关键技能,包括了从需求分析、策划,到账号申请、验证,再到全面的API及开发工具介绍,侧重于服务器端开发。本书也涵盖了盛派网络团队在多年的研发过中收集到的大量注意点,帮助开发者“避坑”。
本书包含了四个部分:微信基础介绍(第1~3章)、Senparc.Weixin SDK框架介绍(第4~13章)、Senparc.Weixin SDK接口介绍(第14~19章)和微信小程序(第20章),由浅入深指导开发者学习微信开发,在此过程中可以结合配套系统进行阅读和练习:https://book.weixin.senparc.com。
同时,本书也是Senparc.Weixin SDK作者为开发者奉上的一份官方文档,书中详细介绍了SDK中各个接口的位置及用法,可以帮助开发者灵活应用和改写代码。对于需要学习编程架构思想的开发者,本书也凝结了较多精华的思想和思考过程,可以作为参考。
Senparc.Weixin SDK已经支持了多个.NET版本,包括.NET Core、.NET Framework 4.5和.NET Framework 4.0,各个版本的接口和使用方法保持了高度的一致,本书以目前使用率zui高的.NET 4.5(C#)版本为例进行介绍,针对其他框架本书也同样适用,读者可以举一反三。
本书除提供给专业开发人员使用以外,也适合大专院校、培训机构作为相关教材和参考书使用。
苏震巍,苏州盛泽人氏,香港理工大学信息管理硕士、微软 Ignite 技术大会讲师、高级电子商务师、中级物流师。
苏州盛派网络科技有限公司创始人,首席架构师。
专注于软件及互联网开发已有 24 年,所著图书《ASP.NET 3.5+SQL Server网站模块化开发全程实录》已被多所大学选为教材。
主持了众多大型项目的架构、开发和集成,对物联网、大数据和人工智能相关技术有深入的实践和理解,已为十余家世界 500 强企业提供解决方案和技术支持。
作为“中国 HTML5 研究小组”首批成员,带领发布了国内shou个HTML5 商业应用,并一直进行着 HTML5 商业化应用的实践和分享。
zui早进入微信开发领域的开拓者之一,开源发布的 Senparc.Weixin SDK 框架是目前使用率zui高的微信 .NET SDK,同时也是国内zui受欢迎的 .NET 开源项目之一。
★第一部分 微信基础介绍
第1章 使用本书 2
第2章 策划你的第一个微信项目 10
第3章 开发微信公众号前的准备 29
★第二部分 Senparc.Weixin SDK框架介绍
第4章 Senparc.Weixin SDK设计架构 58
第5章 微信公众号开发全过程案例 83
第6章 使用SDK Demo:Senparc.Weixin.MP.Sample 117
第7章 MessageHandler:简化消息处理流程 158
第8章 缓存策略 204
第9章 并发场景下的分布式锁 231
第10章 Container:数据容器 243
第11章 SenparcMessageQueue:消息队列 266
第12章 接口调用及数据请求 279
第13章 Debug模式及异常处理 303
第14章 微信接口 318
第15章 模板消息 367
第16章 微信网页授权(OAuth 2.0) 384
第17章 其他帮助类及辅助接口 420
第18章 微信网页开发:JS-SDK 437
第19章 微信支付 462
★第四部分 微信小程序
第20章 微信小程序 522
推荐序
互联网所催生的新一轮产业革命,移动App不断地连接着“人”,创造了一个个基于人的应用场景;物联网传感器在不断地连接着“物”,也在创造一个个基于物的应用场景。在这样一个连接的时代诞生的微信,它不仅成为我们连接人的日常沟通交流的工具,也已经成为了中国整个社会的信息基础设施。在国内,由于微信在实时地连接每一个人,它已经成为一个最强大的入口,我本身从事微信支付的后端清算业务,能够深刻地体验到微信的强大引力,同时我也在运营微信公众号。公众号,服务号和企业号的诞生已经让微信开始连接后端的企业系统,小程序正在发展过程中,小程序让微信连接后端的企业系统打开新的窗户。但是这些后端的企业系统很多都是用C#开发的,正好C#的开源项目Senparc.Weixin SDK成为.NET平台上进行微信快速开发的一个好工具,让开发者更好地对接后端的企业系统。
Senparc.Weixin SDK从诞生起就采用开源模式持续更新,Senparc.Weixin SDK是目前使用率最高的微信.NET SDK,也是国内最受欢迎的.NET开源项目之一,已经支持几乎所有微信平台模块和接口,同时支持 .NET 4.0 / 4.5 / .NET Core。很早我知道本书作者苏震巍在众筹写一本《微信公众平台快速开发》(原名)的书,在小程序对外正式发布的时候,我找他约稿了一篇小程序的文章发在我的微信公众号,那篇文章也是这本书其中的一章内容,最近这本书接近发稿了,有幸为这本书写序。
认识苏震巍多年,知道他不仅是技术专家,也是热心公益、乐于分享助人的好朋友。就如他自己所言,促使他开始准备创作这本书的初心是要帮助朋友,帮助更多有理想的开发者实现价值,倡导开放共享的开发生态圈,助力中国开源事业,同时也感恩一路上给我们提供帮助的朋友们。
阅读完苏震巍传给我的书稿,这是一本比较全面地介绍微信公众号开发技术的图书,是一本从实践总结出来的实战类书籍,各章节的安排具有一定的知识层次,推荐给广大.NET开发者,非常感谢苏震巍夜以继日的辛苦努力,能让广大开发者拿到详实的微信开发指南和参考资料。我很高兴能为这本书作序!可以说,《微信开发深度解析:公众号、小程序高效开发秘籍》这本书是这个时代带给中国.NET开发人员的及时雨,不仅仅告诉我们微信公众平台、小程序的开发和使用,也为我们设计应用系统提供很好的参考和借鉴的经验。
张善友
微软最有价值专家,腾讯高级工程师
12.1 设计规则
微信官方接口的通信方式有 GET 和 POST 两种。前者主要用于从微信服务器拉取信息,例如用户的信息、菜单状态等;后者更多用于文件的上传及支付等对安全性要求更高的接口。
我们统计了这两种方式的请求在微信公众号接口中的占比,大概为 3:2 的比例。
请求的协议多数是 HTTPS(也是官方推荐的),最初有部分上传、下载的接口使用的是 HTTP 协议,日前微信官方已经提供了全覆盖的 HTTPS 协议接口。
注意:虽然目前的大部分接口使用 HTTP 也可以调用,但是经过我们的大量测试,HTTP 和 HTTPS 处理的通道似乎完全不一样,甚至返回的结果也存在差异,所以更加推荐统一使用 HTTPS 协议进行访问。
的 Utilities/HttpUtility/ 下,对于 GET 和 POST 方法分别提供了同步和异步两套完整的方法。其总体的结构如图12-1所示 252#361。
在充分考虑对微信接口优化的基础上,以上这些方法都已被标记为 public static,除了 SDK 内部会使用到这些方法,开发者也可以在外部进行调用,这些方法都已经考虑到了足够的通用性,即使是常规的 HTTP 请求,也可以直接使用其中的方法。
12.2 响应类型
本节介绍微信的接口的响应类型。
12.2.1 基类:WxJsonResult
微信接口的响应数据通常为 JSON 格式,并且几乎每条消息都具有两个相同的键:errmsg 和 errcode,例如以下信息代表请求成功 254#492:
{"errmsg":"ok", "errcode":0}
返回结果中,和 errmsg、errcode 并列的还可能有其他键值,所以我们为所有的返回结果类型定义了一个基类:WxJsonResult,位于 Senparc.Weixin.Entities 命名空间下 254#157:
using System;
namespace Senparc.Weixin.Entities
{
/// <summary>
/// 公众号JSON返回结果(用于菜单接口等)
/// </summary>
[Serializable]
public class WxJsonResult : IWxJsonResult
{
public ReturnCode errcode { get; set; }
public string errmsg { get; set; }
}
}
其中IWxJsonResult 接口定义如下 254#398:
public interface IWxJsonResult : IJsonResult
{
ReturnCode errcode { get; set; }
}
IWxJsonResult 接口又继承了 IJsonResult 接口:
public interface IJsonResult
{
string errmsg { get; set; }
}
将 errcode 和 errmsg 分离到两个(层)接口中,是因为微信企业号等其他模块对于同样的 errcode 属性有着不同的定义,需要对errcode再次进行抽象,这才有了 IWxJsonResult 接口。而string 类型的 errmsg 又是多个模块所共有的,因此放在更加底层的 IJsonResult 接口中。
errcode 在返回的 JSON 中为 int 类型,此处为了方便开发,我们将其定义为一个名为 ReturnCode 的枚举属性,这样就兼顾了数值(int)和文字(string)情景下的开发和阅读需要。
参照官方的 errcode 值和文字说明的定义,ReturnCode 的定义代码见: 254#158。
以上这些错误类型及对应的代码开发者至少应该有大致的印象,在实际开发的过程中,很多错误是非常容易碰到的,这时候我们只能通过错误类型去判断问题所在。
12.2.2 扩展响应类型
WxJsonResult 是所有返回类型的基类,对于不同的接口,SDK 都会定义不同的类来对应其返回结果,例如在“短址接口”中,微信官方返回的 JSON 为 255#159:
{'errmsg':'ok', 'errcode':0, short_url:'http://weixin.senparc.com'}
返回结果的类应该被定义为 255#399:
/// <summary>
/// ShortUrl返回结果
/// </summary>
public class ShortUrlResult : WxJsonResult
{
public string short_url { get; set; }
}
也有一些返回类型会更加复杂,例如多层嵌套,我们同样创建不同层次的类和属性来进行结构一致的匹配。
例如,在“批量获取用户基本信息”接口中,返回数据是以数组的形式表现的,我们会得到类似如下的 JSON 结果 255#160:
{
"user_info_list": [
{
"subscribe": 1,
"openid": "otvxTs4dckWG7imySrJd6jSi0CWE",
"nickname": "iWithery",
"sex": 1,
"language": "zh_CN",
"city": "Jieyang",
"province": "Guangdong",
"country": "China",
"headimgurl": "http://wx.qlogo.cn/mmopen/xbIQx1GRqdvyqkMMhEaGOX802l1CyqMJNgUzKP8MeAeHFicRDSnZH7FY4XB7p8XHXIf6uJA2SCun
TPicGKezDC4saKISzRj3nz/0",
"subscribe_time": 1434093047,
"unionid": "oR5GjjgEhCMJFyzaVZdrxZ2zRRF4",
"remark": "",
"groupid": 0,
"tagid_list":[128,2]
},
{
"subscribe": 0,
"openid": "otvxTs_JZ6SEiP0imdhpi50fuSZg",
"unionid": "oR5GjjjrbqBZbrnPwwmSxFukE41U",
},
{…}
]
}
此时除了可能得到的 errmsg 和 errcode 参数以外,还需要构建一个数组,数组中的元素又是一个复杂对象。对于这样的情况,我们通过创建一个复杂对象的类 UserInfoJson,并将这个类的列表(通常为 List< UserInfoJson>或UserInfoJson[])作为一个属性放入整个返回数据的类中,代码如下 255#161:
/// <summary>
/// 高级接口获取的用户信息
/// </summary>
public class UserInfoJson
{
/// <summary>
/// 用户是否订阅该公众号标识,值为0时,代表此用户没有关注该公众号,拉取不到其余信息。
/// </summary>
public int subscribe { get; set; }
public string openid { get; set; }
public string nickname { get; set; }
public int sex { get; set; }
public string language { get; set; }
public string city { get; set; }
public string province { get; set; }
public string country { get; set; }
public string headimgurl { get; set; }
public long subscribe_time { get; set; }
public string unionid { get; set; }
public string remark { get; set; }
public int groupid { get; set; }
}
/// <summary>
/// 批量获取用户基本信息返回结果
/// </summary>
public class BatchGetUserInfoJsonResult : WxJsonResult
{
public List<UserInfoJson> user_info_list { get; set; }
}
其他类似的情况也参照这样的写法,甚至会层层套用更多的类型。
在类名的约定上,遵循如下的规律:
[接口方法名称] + [返回类型] + Result
其中的 [返回类型] 通常为字符串 JSON,所以经常可以看到以 JsonResult 结尾的类。
例如上述接口的方法名称为 BatchGetUserInfo,则对应的返回类型为 BatchGetUserInfoJsonResult。
装 帧:平装
页 数:624页
版 次:第1版
开 本:16开