mirror of
https://gitee.com/fudiwei/DotNetCore.SKIT.FlurlHttpClient.Wechat.git
synced 2025-04-05 08:37:22 +08:00
docs: 完善文档
This commit is contained in:
parent
33928a5318
commit
2e1f3eba89
33
README.md
33
README.md
@ -15,8 +15,8 @@
|
||||
|
||||
## 特性
|
||||
|
||||
- 基于 `Flurl.Http`,可与 `IHttpClientFactory` 集成。
|
||||
- 支持 .NET Framework 4.6.1+、.NET Standard 2.0+、.NET Core 2.0+、.NET 5+。
|
||||
- 基于 `Flurl.Http`。
|
||||
- 支持 .NET Framework 4.6.2+、.NET Standard 2.0+、.NET Core 2.0+、.NET 5.0+ 多目标框架。
|
||||
- 支持 Windows / Linux / macOS 多平台部署。
|
||||
- 支持 `System.Text.Json`(默认)和 `Newtonsoft.Json` 两种序列化方式。
|
||||
- 强类型接口模型。
|
||||
@ -42,24 +42,11 @@
|
||||
|
||||
## Q & A
|
||||
|
||||
### 1. 为什么要“造轮子”?
|
||||
|
||||
这都 2021 年了,官方本身提供的示例代码还只能运行在 .NET Framework on Windows 上;就连 RSA 签名这么基础的东西都没有人封装(确切地说是因为 RSA 有很多种分块模式和填充模式,网上能找到的往往只封装了其中一种,但却未必符合微信的要求);全网很难找到一个封装微信 API 尽可能全的 .NET SDK,开源的项目有不少,但作者能坚持下去的不多。
|
||||
|
||||
于是萌生了自己封装一个库的想法,打算解决这几个痛点,同时也是推广一下微软官方的 `System.Text.Json`。
|
||||
|
||||
### 2. `Flurl.Http` 是什么?
|
||||
### 1. `Flurl.Http` 是什么?
|
||||
|
||||
[`Flurl.Http`](https://flurl.dev/) 是一个轻量级 HTTP 库,是 .NET 中最受欢迎扩展库之一,在 NuGet 上的累计下载量超过 1700 万、日均下载量超过 6 千、GitHub 2.6k Stars(数据统计截至 2021-06-01)。
|
||||
|
||||
与另一个流行的 HTTP 库 [`RestSharp`](https://restsharp.dev/) 相比,`Flurl.Http` 底层基于 `System.Net.Http.HttpClient`,而 `RestSharp` 底层则基于 `System.Net.HttpWebRequest`,前者在多核多线程环境下的性能基准测试中表现要远优于后者,同时也是微软官方目前推荐的 HTTP 客户端方案。
|
||||
|
||||
> 注:微软官方关于 `System.Net.HttpWebRequest` 与 `System.Net.Http.HttpClient` 的说明:
|
||||
>
|
||||
> - [《Microsoft Docs - HttpWebRequest 类(Systen.Net)》](https://docs.microsoft.com/zh-cn/dotnet/api/system.net.httpwebrequest#remarks)
|
||||
> - [《Microsoft Docs - HttpClient 类(Systen.Net.Http)》](https://docs.microsoft.com/zh-cn/dotnet/api/system.net.http.httpclient#httpclient-and-net-core)
|
||||
|
||||
### 3. 本库与盛派微信 SDK(Senparc.Weixin)有什么区别?
|
||||
### 2. 本库与盛派微信 SDK(Senparc.Weixin)有什么区别?
|
||||
|
||||
> 注:[盛派微信 SDK](https://github.com/JeffreySu/WeiXinMPSDK) 是由苏震巍先生发起的国内知名的 .NET 开源项目。
|
||||
|
||||
@ -69,15 +56,7 @@
|
||||
|
||||
- 本库封装了目前微信官方提供的几乎所有 API(极个别不支持的已在各模块文档中列出具体原因);盛派微信 SDK 只提供了常用的 API。
|
||||
|
||||
### 4. 为什么不支持 .NET Framework 4.0 / .NET Framework 4.5?
|
||||
|
||||
直接原因是本项目的依赖库最低支持到 .NET Framework 4.6.1。
|
||||
|
||||
间接原因是为了支持跨平台的 .NET Standard 2.0,只能兼容到 .NET Framework 4.6.1。
|
||||
|
||||
根本原因是微软官方已于 2016 年 1 月 12 日终止了对 .NET Framework 4.6.1 以下版本的技术支持(详情请阅读[官方公告](https://docs.microsoft.com/zh-cn/lifecycle/faq/dotnet-framework))。也就是说,微软已经不再为此提供安全更新,在大部分技术合规要求中这一点都是扣分项,所以建议各位开发者目标框架能升级就升级。
|
||||
|
||||
### 5. 看了源码,发现模型定义里很多同样的代码是复制粘贴的,为什么不使用面向对象中的继承?
|
||||
### 3. 看了源码,发现模型定义里很多同样的代码是复制粘贴的,为什么不使用面向对象中的继承?
|
||||
|
||||
关于这点得吐槽微信提供的 API 了,很显然微信内部也是很多个 Team 在共同开发,每个 Team、甚至每个人的字段命名风格、约束条件、接口规则都大相径庭。就连微信支付虽然 v3 版 API 号称是 “RESTful” 的,却也没个统一标准。
|
||||
|
||||
@ -87,7 +66,7 @@
|
||||
|
||||
本项目已经尽可能在条件允许的范围内抽象出了一些公共基类、并封装了各种奇怪场景下的自定义 JsonConverter。
|
||||
|
||||
### 6. 所有 API 都经过了测试吗?
|
||||
### 4. 所有 API 都经过了测试吗?
|
||||
|
||||
由于微信的产品业务线众多,很多业务也需要前置条件才能继续,截至目前本项目已封装超过 2300 余个 API,虽然同时也编写了若干单元测试用例,但与数量庞大的 API 相比仍远远不够。
|
||||
|
||||
|
79
docs/WechatApi/Migration_V3.md
Normal file
79
docs/WechatApi/Migration_V3.md
Normal file
@ -0,0 +1,79 @@
|
||||
## v3.x 迁移指南
|
||||
|
||||
v3.x 版本是一个主要版本,其中包括了一些破坏性的变化。从 v2.x 升级到 v3.x 之前,请仔细阅读本文档。
|
||||
|
||||
---
|
||||
|
||||
### 目标框架和框架的变更
|
||||
|
||||
微软官方已与 2022 年 4 月 26 日宣布中止对 .NET Framework 4.6.1 的支持。因此,本项目的最低运行时要求调整为 .NET Framework 4.6.2。
|
||||
|
||||
与此同时,相关的 .NET 基础库(即通常在 `System.*` 或 `Microsoft.*` 命名空间下的内置类型)版本对齐至 .NET 8.0。
|
||||
|
||||
### `Flurl.Http` 的变更
|
||||
|
||||
本库所依赖的 `Flurl.Http` 版本已升级至 v4.0.0,并由此带来一些底层的破坏性变化。
|
||||
|
||||
通常情况下,开发者不需要关注这些变化,除非你正在自定义额外的 API 接口。
|
||||
|
||||
### 新的构造器模式
|
||||
|
||||
随着 `Flurl.Http` 的升级,原有的与 `IHttpClientFactory` 集成的方式发生了根本性的改变。
|
||||
|
||||
为了应对这种变化(请参阅本文档[《如何与 `IHttpClientFactory` 集成?》](./Advanced_IHttpClientFactory.md)),也为了日后能更加灵活地配置客户端,我们在新版本中提供了构造器模式来构造客户端:
|
||||
|
||||
```csharp
|
||||
var options = new WechatApiClientOptions() { /* 具体配置项略 */ };
|
||||
var client = WechatApiClientBuilder.Create(options).Build();
|
||||
```
|
||||
|
||||
当然,原有的实例化方式仍然可用:
|
||||
|
||||
```csharp
|
||||
var options = new WechatApiClientOptions() { /* 具体配置项略 */ };
|
||||
var client = new WechatApiClient(options);
|
||||
```
|
||||
|
||||
### 基础类型:`SKIT.FlurlHttpClient.Primitives.EncodedeString`
|
||||
|
||||
在进行加解密或哈希等操作时,参与运算的数据和最终得到的结果通常是字节数组(即 `byte[]`)形式。而在实际应用中,我们常常需要将这些字节序列转换成文本格式。我们发现即便是同一种加解密或哈希算法,在不同平台上所需要的编码方式也可能不同。比如同为 SHA256,在某些接口中需要转换为十六进制(HEX)编码传参,而在另一些接口中却需要转换为 Base64 编码传参。
|
||||
|
||||
在过往的版本中,我们在不同的模块中针对不同平台的要求提供了单独的封装方法,这使得代码更加分散且不易维护。
|
||||
|
||||
为了统一处理并简化这些差异,我们在公共组件中引入了 `EncodedString` 这一类型。`EncodedString` 类型是一个封装结构,它提供了统一的接口来处理不同编码方式的字符串。通过该类型,开发者可以不必关心底层使用的是哪种编码方式,从而使代码更加简洁和清晰。
|
||||
|
||||
幸运的是,为了简化升级的难度,`EncodedString` 仍可以与 `String` 类型互相转换:
|
||||
|
||||
```csharp
|
||||
// string → EncodedString
|
||||
string str = "U0tJVC5GbHVybEh0dHBDbGllbnQgaXMgQVdFU09NRSE=";
|
||||
EncodedString estr = (EncodedString)str;
|
||||
|
||||
// EncodedString → string
|
||||
EncodedString estr = new EncodedString("U0tJVC5GbHVybEh0dHBDbGllbnQgaXMgQVdFU09NRSE=", EncodingKinds.Base64);
|
||||
string str = (string)estr;
|
||||
```
|
||||
|
||||
涉及到变化的包括 `AESUtility`、`SHA1Utility`、`HMACUtility` 等工具类。
|
||||
|
||||
### 基础类型:`SKIT.FlurlHttpClient.Primitives.ErroredResult`
|
||||
|
||||
在进行数据验签等操作时,由于传入了错误的参数导致抛出异常,通常需要被视为验签失败。
|
||||
|
||||
在过往的版本中,我们在相应的方法内部 `try-catch` 捕获所有异常,并直接返回 `false`。然而,这种做法虽然简化了返回值的处理,但却严重限制了开发者错误调试的能力,因为它无法提供关于异常的详细信息。虽然有部分方法提供了带有 `(..., out Exception error)` 引用参数的重载,但却不能在异步方法中所使用。
|
||||
|
||||
为了解决这一问题,我们在公共组件中引入了 `ErroredResult` 这一类型。`ErroredResult` 类型是一个封装结构,它不仅可以在逻辑上表示操作的成功与否,而且能够携带发生的异常信息,极大地便利了异常处理和调试过程。
|
||||
|
||||
幸运的是,为了简化升级的难度,`ErroredResult` 仍可以与 `Boolean` 类型互相转换:
|
||||
|
||||
```csharp
|
||||
// Boolean → ErroredResult
|
||||
bool ret = true;
|
||||
ErroredResult eret = (ErroredResult)ret;
|
||||
|
||||
// ErroredResult → Boolean
|
||||
ErroredResult eret = new ErroredResult(true);
|
||||
bool ret = (bool)eret;
|
||||
```
|
||||
|
||||
涉及到变化的包括 `VerifyEventSignatureFromJson()`、`VerifyEventSignatureFromXml()` 等扩展方法。
|
@ -108,3 +108,10 @@ else
|
||||
为方便开发者快速掌握本库的使用方法,这里提供一个示例项目以供参考。
|
||||
|
||||
请阅读[《示例项目说明》](./Sample.md)。
|
||||
|
||||
---
|
||||
|
||||
## 迁移指南
|
||||
|
||||
- [v3.x 迁移指南](./Migration_V3.md)
|
||||
|
||||
|
@ -19,7 +19,7 @@ bool ret = client.VerifyEventSignature(
|
||||
|
||||
### 调试验签错误:
|
||||
|
||||
由于 `VerifyEventSignature()` 方法内部会 `try-catch` 掉所有异常情况,并直接返回 `false`。为方便开发者在调试阶段排查验签的错误信息,你可以在验证回调通知事件签名时指定返回值类型为 `ErroredResult` 而非 `Boolean`,该返回值中包含了一些异常的原因和相关堆栈信息。
|
||||
由于 `VerifyEventSignature()` 方法内部会 `try-catch` 捕获所有异常,并直接返回 `false`。为方便开发者在调试阶段排查验签的错误信息,你可以在验证回调通知事件签名时指定返回值类型为 `ErroredResult` 而非 `Boolean`,该返回值中包含了一些异常的原因和相关堆栈信息。
|
||||
|
||||
```csharp
|
||||
ErroredResult res = client.VerifyEventSignature(authorization, signature);
|
||||
|
@ -25,7 +25,7 @@ bool ret = client.VerifyResponseSignature(response);
|
||||
|
||||
### 调试验签错误:
|
||||
|
||||
由于 `VerifyResponseSignature()` 方法内部会 `try-catch` 掉所有异常情况,并直接返回 `false`。为方便开发者在调试阶段排查验签的错误信息,你可以在验证响应签名时指定返回值类型为 `ErroredResult` 而非 `Boolean`,该返回值中包含了一些异常的原因和相关堆栈信息。
|
||||
由于 `VerifyResponseSignature()` 方法内部会 `try-catch` 捕获所有异常,并直接返回 `false`。为方便开发者在调试阶段排查验签的错误信息,你可以在验证响应签名时指定返回值类型为 `ErroredResult` 而非 `Boolean`,该返回值中包含了一些异常的原因和相关堆栈信息。
|
||||
|
||||
```csharp
|
||||
ErroredResult res = client.VerifyResponseSignature(response);
|
||||
|
79
docs/WechatTenpayV2/Migration_V3.md
Normal file
79
docs/WechatTenpayV2/Migration_V3.md
Normal file
@ -0,0 +1,79 @@
|
||||
## v3.x 迁移指南
|
||||
|
||||
v3.x 版本是一个主要版本,其中包括了一些破坏性的变化。从 v2.x 升级到 v3.x 之前,请仔细阅读本文档。
|
||||
|
||||
---
|
||||
|
||||
### 目标框架和框架的变更
|
||||
|
||||
微软官方已与 2022 年 4 月 26 日宣布中止对 .NET Framework 4.6.1 的支持。因此,本项目的最低运行时要求调整为 .NET Framework 4.6.2。
|
||||
|
||||
与此同时,相关的 .NET 基础库(即通常在 `System.*` 或 `Microsoft.*` 命名空间下的内置类型)版本对齐至 .NET 8.0。
|
||||
|
||||
### `Flurl.Http` 的变更
|
||||
|
||||
本库所依赖的 `Flurl.Http` 版本已升级至 v4.0.0,并由此带来一些底层的破坏性变化。
|
||||
|
||||
通常情况下,开发者不需要关注这些变化,除非你正在自定义额外的 API 接口。
|
||||
|
||||
### 新的构造器模式
|
||||
|
||||
随着 `Flurl.Http` 的升级,原有的与 `IHttpClientFactory` 集成的方式发生了根本性的改变。
|
||||
|
||||
为了应对这种变化(请参阅本文档[《如何与 `IHttpClientFactory` 集成?》](./Advanced_IHttpClientFactory.md)),也为了日后能更加灵活地配置客户端,我们在新版本中提供了构造器模式来构造客户端:
|
||||
|
||||
```csharp
|
||||
var options = new WechatTenpayClientOptions() { /* 具体配置项略 */ };
|
||||
var client = WechatTenpayClientBuilder.Create(options).Build();
|
||||
```
|
||||
|
||||
当然,原有的实例化方式仍然可用:
|
||||
|
||||
```csharp
|
||||
var options = new WechatTenpayClientOptions() { /* 具体配置项略 */ };
|
||||
var client = new WechatTenpayClient(options);
|
||||
```
|
||||
|
||||
### 基础类型:`SKIT.FlurlHttpClient.Primitives.EncodedeString`
|
||||
|
||||
在进行加解密或哈希等操作时,参与运算的数据和最终得到的结果通常是字节数组(即 `byte[]`)形式。而在实际应用中,我们常常需要将这些字节序列转换成文本格式。我们发现即便是同一种加解密或哈希算法,在不同平台上所需要的编码方式也可能不同。比如同为 SHA256,在某些接口中需要转换为十六进制(HEX)编码传参,而在另一些接口中却需要转换为 Base64 编码传参。
|
||||
|
||||
在过往的版本中,我们在不同的模块中针对不同平台的要求提供了单独的封装方法,这使得代码更加分散且不易维护。
|
||||
|
||||
为了统一处理并简化这些差异,我们在公共组件中引入了 `EncodedString` 这一类型。`EncodedString` 类型是一个封装结构,它提供了统一的接口来处理不同编码方式的字符串。通过该类型,开发者可以不必关心底层使用的是哪种编码方式,从而使代码更加简洁和清晰。
|
||||
|
||||
幸运的是,为了简化升级的难度,`EncodedString` 仍可以与 `String` 类型互相转换:
|
||||
|
||||
```csharp
|
||||
// string → EncodedString
|
||||
string str = "U0tJVC5GbHVybEh0dHBDbGllbnQgaXMgQVdFU09NRSE=";
|
||||
EncodedString estr = (EncodedString)str;
|
||||
|
||||
// EncodedString → string
|
||||
EncodedString estr = new EncodedString("U0tJVC5GbHVybEh0dHBDbGllbnQgaXMgQVdFU09NRSE=", EncodingKinds.Base64);
|
||||
string str = (string)estr;
|
||||
```
|
||||
|
||||
涉及到变化的包括 `AESUtility`、`MD5Utility`、`HMACUtility` 等工具类。
|
||||
|
||||
### 基础类型:`SKIT.FlurlHttpClient.Primitives.ErroredResult`
|
||||
|
||||
在进行数据验签等操作时,由于传入了错误的参数导致抛出异常,通常需要被视为验签失败。
|
||||
|
||||
在过往的版本中,我们在相应的方法内部 `try-catch` 捕获所有异常,并直接返回 `false`。然而,这种做法虽然简化了返回值的处理,但却严重限制了开发者错误调试的能力,因为它无法提供关于异常的详细信息。虽然有部分方法提供了带有 `(..., out Exception error)` 引用参数的重载,但却不能在异步方法中所使用。
|
||||
|
||||
为了解决这一问题,我们在公共组件中引入了 `ErroredResult` 这一类型。`ErroredResult` 类型是一个封装结构,它不仅可以在逻辑上表示操作的成功与否,而且能够携带发生的异常信息,极大地便利了异常处理和调试过程。
|
||||
|
||||
幸运的是,为了简化升级的难度,`ErroredResult` 仍可以与 `Boolean` 类型互相转换:
|
||||
|
||||
```csharp
|
||||
// Boolean → ErroredResult
|
||||
bool ret = true;
|
||||
ErroredResult eret = (ErroredResult)ret;
|
||||
|
||||
// ErroredResult → Boolean
|
||||
ErroredResult eret = new ErroredResult(true);
|
||||
bool ret = (bool)eret;
|
||||
```
|
||||
|
||||
涉及到变化的包括 `VerifyResponseSignature()`、`VerifyEventSignature()` 等扩展方法。
|
@ -101,3 +101,9 @@ else
|
||||
- [如何指定 JSON 序列化器?](./Advanced_JsonSerializer.md)
|
||||
|
||||
- [如何使用拦截器?](./Advanced_Interceptor.md)
|
||||
|
||||
---
|
||||
|
||||
## 迁移指南
|
||||
|
||||
- [v3.x 迁移指南](./Migration_V3.md)
|
||||
|
@ -51,7 +51,7 @@ bool ret = client.VerifyEventSignature(
|
||||
|
||||
### 调试验签错误:
|
||||
|
||||
由于 `VerifyEventSignature()` 方法内部会 `try-catch` 掉所有异常情况,并直接返回 `false`。为方便开发者在调试阶段排查验签的错误信息,你可以在验证回调通知事件签名时指定返回值类型为 `ErroredResult` 而非 `Boolean`,该返回值中包含了一些异常的原因和相关堆栈信息。
|
||||
由于 `VerifyEventSignature()` 方法内部会 `try-catch` 捕获所有异常,并直接返回 `false`。为方便开发者在调试阶段排查验签的错误信息,你可以在验证回调通知事件签名时指定返回值类型为 `ErroredResult` 而非 `Boolean`,该返回值中包含了一些异常的原因和相关堆栈信息。
|
||||
|
||||
```csharp
|
||||
ErroredResult res = client.VerifyEventSignature(timestamp, nonce, body, signature, serialNumber);
|
||||
|
@ -60,7 +60,7 @@ bool ret = client.VerifyResponseSignature(response);
|
||||
|
||||
### 调试验签错误:
|
||||
|
||||
由于 `VerifyResponseSignature()` 方法内部会 `try-catch` 掉所有异常情况,并直接返回 `false`。为方便开发者在调试阶段排查验签的错误信息,你可以在验证响应签名时指定返回值类型为 `ErroredResult` 而非 `Boolean`,该返回值中包含了一些异常的原因和相关堆栈信息。
|
||||
由于 `VerifyResponseSignature()` 方法内部会 `try-catch` 捕获所有异常,并直接返回 `false`。为方便开发者在调试阶段排查验签的错误信息,你可以在验证响应签名时指定返回值类型为 `ErroredResult` 而非 `Boolean`,该返回值中包含了一些异常的原因和相关堆栈信息。
|
||||
|
||||
```csharp
|
||||
ErroredResult res = client.VerifyResponseSignature(response);
|
||||
|
87
docs/WechatTenpayV3/Migration_V3.md
Normal file
87
docs/WechatTenpayV3/Migration_V3.md
Normal file
@ -0,0 +1,87 @@
|
||||
## v3.x 迁移指南
|
||||
|
||||
v3.x 版本是一个主要版本,其中包括了一些破坏性的变化。从 v2.x 升级到 v3.x 之前,请仔细阅读本文档。
|
||||
|
||||
---
|
||||
|
||||
### 目标框架和框架的变更
|
||||
|
||||
微软官方已与 2022 年 4 月 26 日宣布中止对 .NET Framework 4.6.1 的支持。因此,本项目的最低运行时要求调整为 .NET Framework 4.6.2。
|
||||
|
||||
与此同时,相关的 .NET 基础库(即通常在 `System.*` 或 `Microsoft.*` 命名空间下的内置类型)版本对齐至 .NET 8.0。
|
||||
|
||||
### `Flurl.Http` 的变更
|
||||
|
||||
本库所依赖的 `Flurl.Http` 版本已升级至 v4.0.0,并由此带来一些底层的破坏性变化。
|
||||
|
||||
通常情况下,开发者不需要关注这些变化,除非你正在自定义额外的 API 接口。
|
||||
|
||||
### 新的构造器模式
|
||||
|
||||
随着 `Flurl.Http` 的升级,原有的与 `IHttpClientFactory` 集成的方式发生了根本性的改变。
|
||||
|
||||
为了应对这种变化(请参阅本文档[《如何与 `IHttpClientFactory` 集成?》](./Advanced_IHttpClientFactory.md)),也为了日后能更加灵活地配置客户端,我们在新版本中提供了构造器模式来构造客户端:
|
||||
|
||||
```csharp
|
||||
var options = new WechatTenpayClientOptions() { /* 具体配置项略 */ };
|
||||
var client = WechatTenpayClientBuilder.Create(options).Build();
|
||||
```
|
||||
|
||||
当然,原有的实例化方式仍然可用:
|
||||
|
||||
```csharp
|
||||
var options = new WechatTenpayClientOptions() { /* 具体配置项略 */ };
|
||||
var client = new WechatTenpayClient(options);
|
||||
```
|
||||
|
||||
### 基础类型:`SKIT.FlurlHttpClient.Primitives.EncodedeString`
|
||||
|
||||
在进行加解密或哈希等操作时,参与运算的数据和最终得到的结果通常是字节数组(即 `byte[]`)形式。而在实际应用中,我们常常需要将这些字节序列转换成文本格式。我们发现即便是同一种加解密或哈希算法,在不同平台上所需要的编码方式也可能不同。比如同为 SHA256,在某些接口中需要转换为十六进制(HEX)编码传参,而在另一些接口中却需要转换为 Base64 编码传参。
|
||||
|
||||
在过往的版本中,我们在不同的模块中针对不同平台的要求提供了单独的封装方法,这使得代码更加分散且不易维护。
|
||||
|
||||
为了统一处理并简化这些差异,我们在公共组件中引入了 `EncodedString` 这一类型。`EncodedString` 类型是一个封装结构,它提供了统一的接口来处理不同编码方式的字符串。通过该类型,开发者可以不必关心底层使用的是哪种编码方式,从而使代码更加简洁和清晰。
|
||||
|
||||
幸运的是,为了简化升级的难度,`EncodedString` 仍可以与 `String` 类型互相转换:
|
||||
|
||||
```csharp
|
||||
// string → EncodedString
|
||||
string str = "U0tJVC5GbHVybEh0dHBDbGllbnQgaXMgQVdFU09NRSE=";
|
||||
EncodedString estr = (EncodedString)str;
|
||||
|
||||
// EncodedString → string
|
||||
EncodedString estr = new EncodedString("U0tJVC5GbHVybEh0dHBDbGllbnQgaXMgQVdFU09NRSE=", EncodingKinds.Base64);
|
||||
string str = (string)estr;
|
||||
```
|
||||
|
||||
涉及到变化的包括 `AESUtility`、`RSAUtility`、`SHA256Utility`、`SM2Utility`、`SM3Utility`、`SM4Utility` 等工具类。
|
||||
|
||||
### 基础类型:`SKIT.FlurlHttpClient.Primitives.ErroredResult`
|
||||
|
||||
在进行数据验签等操作时,由于传入了错误的参数导致抛出异常,通常需要被视为验签失败。
|
||||
|
||||
在过往的版本中,我们在相应的方法内部 `try-catch` 捕获所有异常,并直接返回 `false`。然而,这种做法虽然简化了返回值的处理,但却严重限制了开发者错误调试的能力,因为它无法提供关于异常的详细信息。虽然有部分方法提供了带有 `(..., out Exception error)` 引用参数的重载,但却不能在异步方法中所使用。
|
||||
|
||||
为了解决这一问题,我们在公共组件中引入了 `ErroredResult` 这一类型。`ErroredResult` 类型是一个封装结构,它不仅可以在逻辑上表示操作的成功与否,而且能够携带发生的异常信息,极大地便利了异常处理和调试过程。
|
||||
|
||||
幸运的是,为了简化升级的难度,`ErroredResult` 仍可以与 `Boolean` 类型互相转换:
|
||||
|
||||
```csharp
|
||||
// Boolean → ErroredResult
|
||||
bool ret = true;
|
||||
ErroredResult eret = (ErroredResult)ret;
|
||||
|
||||
// ErroredResult → Boolean
|
||||
ErroredResult eret = new ErroredResult(true);
|
||||
bool ret = (bool)eret;
|
||||
```
|
||||
|
||||
涉及到变化的包括 `VerifyResponseSignature()`、`VerifyEventSignature()` 等扩展方法。
|
||||
|
||||
### 新的平台证书管理器
|
||||
|
||||
原有的平台证书管理器由抽象类型 `CertificateManager` 调整为接口 `ICertificateManager`。
|
||||
|
||||
同时,我们提供了新的 `ICertificateManagerAsync` 接口,开发者可以基于此自定义异步的密钥管理器实现。然后,你就可以调用 `VerifyResponseSignatureAsync()`、`VerifyEventSignatureAsync()`、`EncryptRequestSensitivePropertyAsync()` 等新的扩展方法,来异步地执行原本的业务流程了。
|
||||
|
||||
此外,我们废弃了原本的 `CertificateEntry` 的一个构造函数 `CertificateEntry(QueryCertificatesResponse.Types.Certificate model)` 重载。取而代之的是新的静态方法 `CertificateEntry.Parse(QueryCertificatesResponse.Types.Certificate model)`。
|
@ -127,3 +127,9 @@ else
|
||||
为方便开发者快速掌握本库的使用方法,这里提供一个示例项目以供参考。
|
||||
|
||||
请阅读[《示例项目说明》](./Sample.md)。
|
||||
|
||||
---
|
||||
|
||||
## 迁移指南
|
||||
|
||||
- [v3.x 迁移指南](./Migration_V3.md)
|
||||
|
85
docs/WechatWork/Migration_V3.md
Normal file
85
docs/WechatWork/Migration_V3.md
Normal file
@ -0,0 +1,85 @@
|
||||
## v3.x 迁移指南
|
||||
|
||||
v3.x 版本是一个主要版本,其中包括了一些破坏性的变化。从 v2.x 升级到 v3.x 之前,请仔细阅读本文档。
|
||||
|
||||
---
|
||||
|
||||
### 目标框架和框架的变更
|
||||
|
||||
微软官方已与 2022 年 4 月 26 日宣布中止对 .NET Framework 4.6.1 的支持。因此,本项目的最低运行时要求调整为 .NET Framework 4.6.2。
|
||||
|
||||
与此同时,相关的 .NET 基础库(即通常在 `System.*` 或 `Microsoft.*` 命名空间下的内置类型)版本对齐至 .NET 8.0。
|
||||
|
||||
### `Flurl.Http` 的变更
|
||||
|
||||
本库所依赖的 `Flurl.Http` 版本已升级至 v4.0.0,并由此带来一些底层的破坏性变化。
|
||||
|
||||
通常情况下,开发者不需要关注这些变化,除非你正在自定义额外的 API 接口。
|
||||
|
||||
### 新的构造器模式
|
||||
|
||||
随着 `Flurl.Http` 的升级,原有的与 `IHttpClientFactory` 集成的方式发生了根本性的改变。
|
||||
|
||||
为了应对这种变化(请参阅本文档[《如何与 `IHttpClientFactory` 集成?》](./Advanced_IHttpClientFactory.md)),也为了日后能更加灵活地配置客户端,我们在新版本中提供了构造器模式来构造客户端:
|
||||
|
||||
```csharp
|
||||
var options = new WechatWorkClientOptions() { /* 具体配置项略 */ };
|
||||
var client = WechatWorkClientBuilder.Create(options).Build();
|
||||
```
|
||||
|
||||
当然,原有的实例化方式仍然可用:
|
||||
|
||||
```csharp
|
||||
var options = new WechatWorkClientOptions() { /* 具体配置项略 */ };
|
||||
var client = new WechatWorkClient(options);
|
||||
```
|
||||
|
||||
### 基础类型:`SKIT.FlurlHttpClient.Primitives.EncodedeString`
|
||||
|
||||
在进行加解密或哈希等操作时,参与运算的数据和最终得到的结果通常是字节数组(即 `byte[]`)形式。而在实际应用中,我们常常需要将这些字节序列转换成文本格式。我们发现即便是同一种加解密或哈希算法,在不同平台上所需要的编码方式也可能不同。比如同为 SHA256,在某些接口中需要转换为十六进制(HEX)编码传参,而在另一些接口中却需要转换为 Base64 编码传参。
|
||||
|
||||
在过往的版本中,我们在不同的模块中针对不同平台的要求提供了单独的封装方法,这使得代码更加分散且不易维护。
|
||||
|
||||
为了统一处理并简化这些差异,我们在公共组件中引入了 `EncodedString` 这一类型。`EncodedString` 类型是一个封装结构,它提供了统一的接口来处理不同编码方式的字符串。通过该类型,开发者可以不必关心底层使用的是哪种编码方式,从而使代码更加简洁和清晰。
|
||||
|
||||
幸运的是,为了简化升级的难度,`EncodedString` 仍可以与 `String` 类型互相转换:
|
||||
|
||||
```csharp
|
||||
// string → EncodedString
|
||||
string str = "U0tJVC5GbHVybEh0dHBDbGllbnQgaXMgQVdFU09NRSE=";
|
||||
EncodedString estr = (EncodedString)str;
|
||||
|
||||
// EncodedString → string
|
||||
EncodedString estr = new EncodedString("U0tJVC5GbHVybEh0dHBDbGllbnQgaXMgQVdFU09NRSE=", EncodingKinds.Base64);
|
||||
string str = (string)estr;
|
||||
```
|
||||
|
||||
涉及到变化的包括 `AESUtility`、`RSAUtility`、`SHA1Utility` 等工具类。
|
||||
|
||||
### 基础类型:`SKIT.FlurlHttpClient.Primitives.ErroredResult`
|
||||
|
||||
在进行数据验签等操作时,由于传入了错误的参数导致抛出异常,通常需要被视为验签失败。
|
||||
|
||||
在过往的版本中,我们在相应的方法内部 `try-catch` 捕获所有异常,并直接返回 `false`。然而,这种做法虽然简化了返回值的处理,但却严重限制了开发者错误调试的能力,因为它无法提供关于异常的详细信息。虽然有部分方法提供了带有 `(..., out Exception error)` 引用参数的重载,但却不能在异步方法中所使用。
|
||||
|
||||
为了解决这一问题,我们在公共组件中引入了 `ErroredResult` 这一类型。`ErroredResult` 类型是一个封装结构,它不仅可以在逻辑上表示操作的成功与否,而且能够携带发生的异常信息,极大地便利了异常处理和调试过程。
|
||||
|
||||
幸运的是,为了简化升级的难度,`ErroredResult` 仍可以与 `Boolean` 类型互相转换:
|
||||
|
||||
```csharp
|
||||
// Boolean → ErroredResult
|
||||
bool ret = true;
|
||||
ErroredResult eret = (ErroredResult)ret;
|
||||
|
||||
// ErroredResult → Boolean
|
||||
ErroredResult eret = new ErroredResult(true);
|
||||
bool ret = (bool)eret;
|
||||
```
|
||||
|
||||
涉及到变化的包括 `VerifyEventSignatureForEcho()`、`VerifyEventSignatureFromJson()`、`VerifyEventSignatureFromXml()` 等扩展方法。
|
||||
|
||||
### 企业会话存档 SDK
|
||||
|
||||
原企业会话存档 SDK 客户端的命名空间发生了变化,由 `SKIT.FlurlHttpClient.Wechat.Work.SDK.Finance` 移动至 `SKIT.FlurlHttpClient.Wechat.Work.ExtendedSDK.Finance`。
|
||||
|
||||
同时,我们提供了新的 `IEncryptionKeyManagerAsync` 接口,开发者可以基于此自定义异步的密钥管理器实现。
|
@ -93,3 +93,9 @@ else
|
||||
- [如何指定 JSON 序列化器?](./Advanced_JsonSerializer.md)
|
||||
|
||||
- [如何使用拦截器?](./Advanced_Interceptor.md)
|
||||
|
||||
---
|
||||
|
||||
## 迁移指南
|
||||
|
||||
- [v3.x 迁移指南](./Migration_V3.md)
|
||||
|
@ -1,7 +1,7 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFrameworks>net462; net471; netstandard2.0; net6.0</TargetFrameworks>
|
||||
<TargetFrameworks>net461; net471; netstandard2.0; net6.0</TargetFrameworks>
|
||||
<LangVersion>10.0</LangVersion>
|
||||
<Nullable>enable</Nullable>
|
||||
<NullableReferenceTypes>true</NullableReferenceTypes>
|
||||
@ -36,8 +36,8 @@
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Reference Include="System.Net.Http.WebRequest" Condition="'$(TargetFramework)' == 'net462' Or '$(TargetFramework)' == 'net471'" />
|
||||
<Reference Include="System.Web" Condition="'$(TargetFramework)' == 'net462' Or '$(TargetFramework)' == 'net471'" />
|
||||
<Reference Include="System.Net.Http.WebRequest" Condition="'$(TargetFramework)' == 'net461' Or '$(TargetFramework)' == 'net471'" />
|
||||
<Reference Include="System.Web" Condition="'$(TargetFramework)' == 'net461' Or '$(TargetFramework)' == 'net471'" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
@ -22,7 +22,7 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV2.Settings
|
||||
{
|
||||
X509Certificate x509;
|
||||
|
||||
#if NET471_OR_GREATER || NET5_0_OR_GREATER || NETSTANDARD2_0_OR_GREATER
|
||||
#if NET471_OR_GREATER || NETSTANDARD2_0_OR_GREATER || NET5_0_OR_GREATER
|
||||
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
|
||||
#else
|
||||
if (Environment.OSVersion.Platform == PlatformID.Win32NT)
|
||||
|
@ -82,6 +82,7 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3
|
||||
/// <param name="webhookBody">微信回调通知中请求正文。</param>
|
||||
/// <param name="webhookSignature">微信回调通知中的 "Wechatpay-Signature" 请求标头。</param>
|
||||
/// <param name="webhookSerialNumber">微信回调通知中的 "Wechatpay-Serial" 请求标头。</param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
public static Task<ErroredResult> VerifyEventSignatureAsync(this WechatTenpayClient client, string webhookTimestamp, string webhookNonce, string webhookBody, string webhookSignature, string webhookSerialNumber, CancellationToken cancellationToken = default)
|
||||
{
|
||||
@ -112,6 +113,7 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3
|
||||
/// <param name="webhookSignature">微信回调通知中的 "Wechatpay-Signature" 请求标头。</param>
|
||||
/// <param name="webhookSignatureType">微信回调通知中的 "Wechatpay-Signature-Type" 请求标头。</param>
|
||||
/// <param name="webhookSerialNumber">微信回调通知中的 "Wechatpay-Serial" 请求标头。</param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
public static Task<ErroredResult> VerifyEventSignatureAsync(this WechatTenpayClient client, string webhookTimestamp, string webhookNonce, string webhookBody, string webhookSignature, string webhookSignatureType, string webhookSerialNumber, CancellationToken cancellationToken = default)
|
||||
{
|
||||
|
@ -109,6 +109,7 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3
|
||||
/// <typeparam name="TResponse"></typeparam>
|
||||
/// <param name="client"></param>
|
||||
/// <param name="response"></param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
public static Task<ErroredResult> VerifyResponseSignatureAsync<TResponse>(this WechatTenpayClient client, TResponse response, CancellationToken cancellationToken = default)
|
||||
where TResponse : WechatTenpayResponse
|
||||
@ -142,6 +143,7 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3
|
||||
/// <param name="responseBody"></param>
|
||||
/// <param name="responseSignature"></param>
|
||||
/// <param name="responseSerialNumber"></param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
public static Task<ErroredResult> VerifyResponseSignatureAsync(this WechatTenpayClient client, string responseTimestamp, string responseNonce, string responseBody, string responseSignature, string responseSerialNumber, CancellationToken cancellationToken = default)
|
||||
{
|
||||
@ -172,6 +174,7 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3
|
||||
/// <param name="responseSignature"></param>
|
||||
/// <param name="responseSignatureType"></param>
|
||||
/// <param name="responseSerialNumber"></param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
public static Task<ErroredResult> VerifyResponseSignatureAsync(this WechatTenpayClient client, string responseTimestamp, string responseNonce, string responseBody, string responseSignature, string responseSignatureType, string responseSerialNumber, CancellationToken cancellationToken = default)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user