docs: 完善文档

This commit is contained in:
Fu Diwei 2024-02-07 11:22:05 +08:00 committed by RHQYZ
parent 8cf032f25a
commit c774af7466
49 changed files with 181 additions and 171 deletions

View File

@ -1,10 +1,10 @@
## 如何在 ASP.NET Core 中`IHttpClientFactory` 集成?
## 如何与 `IHttpClientFactory` 集成?
---
本功能来自于公共组件,请参阅公共组件下的相关文档:
> [《SKIT.FlurlHttpClient FAQ如何在 ASP.NET Core 中与 IHttpClientFactory 集成?》](https://github.com/fudiwei/DotNetCore.SKIT.FlurlHttpClient/blob/main/docs/FAQ_IHttpClientFactory.md)
> [《SKIT.FlurlHttpClient FAQ如何与 IHttpClientFactory 集成?》](https://github.com/fudiwei/DotNetCore.SKIT.FlurlHttpClient/blob/main/docs/README.md)
---

View File

@ -4,7 +4,7 @@
本功能来自于公共组件,请参阅公共组件下的相关文档:
> [《SKIT.FlurlHttpClient FAQ如何使用拦截器](https://github.com/fudiwei/DotNetCore.SKIT.FlurlHttpClient/blob/main/docs/FAQ_Interceptor.md)
> [《SKIT.FlurlHttpClient FAQ如何使用拦截器](https://github.com/fudiwei/DotNetCore.SKIT.FlurlHttpClient/blob/main/docs/README.md)
---

View File

@ -4,7 +4,7 @@
本功能来自于公共组件,请参阅公共组件下的相关文档:
> [《SKIT.FlurlHttpClient FAQ如何指定 JSON 序列化器?》](https://github.com/fudiwei/DotNetCore.SKIT.FlurlHttpClient/blob/main/docs/FAQ_JsonSerializer.md)
> [《SKIT.FlurlHttpClient FAQ如何指定 JSON 序列化器?》](https://github.com/fudiwei/DotNetCore.SKIT.FlurlHttpClient/blob/main/docs/README.md)
---

View File

@ -16,6 +16,9 @@
## 快速入门
> [!IMPORTANT]
> 此目录下的文档适用于 v3.x 版本的模块。如果你正在使用 2.x 版本,请移步至 GitHub/Gitee 的已归档分支。
### 安装:
提示:如果你使用 Visual Studio NuGet 管理器图形化界面,请在搜索结果中勾选“**包括预发行版**”。
@ -40,7 +43,7 @@ var options = new WechatAdsClientOptions()
AgencyAppId = "广告服务商 AppId",
AgencyApiKey = "广告服务商 ApiKey"
};
var client = new WechatAdsClient(options);
var client = WechatAdsClientBuilder.Create(options).Build();
```
### 请求 & 响应:
@ -63,7 +66,7 @@ var response = await client.ExecuteCampaignsAddAsync(request);
## 基础用法
- [如何快速找到需要调用的 API 模型类名 / 方法名?](./Basic_ModelDefinition.md)
- [如何快速找到需要调用的 API 模型类名 / 方法名?](./Basic_ModelDefinition.md)
- [如何获取接口调用凭据(即 AccessToken](./Basic_AccessToken.md)
@ -71,7 +74,7 @@ var response = await client.ExecuteCampaignsAddAsync(request);
## 高级技巧
- [如何在 ASP.NET Core 中与 `IHttpClientFactory` 集成?](./Advanced_IHttpClientFactory.md)
- [如何与 `IHttpClientFactory` 集成?](./Advanced_IHttpClientFactory.md)
- [如何指定 JSON 序列化器?](./Advanced_JsonSerializer.md)

View File

@ -1,10 +1,10 @@
## 如何在 ASP.NET Core 中`IHttpClientFactory` 集成?
## 如何与 `IHttpClientFactory` 集成?
---
本功能来自于公共组件,请参阅公共组件下的相关文档:
> [《SKIT.FlurlHttpClient FAQ如何在 ASP.NET Core 中与 IHttpClientFactory 集成?》](https://github.com/fudiwei/DotNetCore.SKIT.FlurlHttpClient/blob/main/docs/FAQ_IHttpClientFactory.md)
> [《SKIT.FlurlHttpClient FAQ如何与 IHttpClientFactory 集成?》](https://github.com/fudiwei/DotNetCore.SKIT.FlurlHttpClient/blob/main/docs/README.md)
---

View File

@ -4,7 +4,7 @@
本功能来自于公共组件,请参阅公共组件下的相关文档:
> [《SKIT.FlurlHttpClient FAQ如何使用拦截器](https://github.com/fudiwei/DotNetCore.SKIT.FlurlHttpClient/blob/main/docs/FAQ_Interceptor.md)
> [《SKIT.FlurlHttpClient FAQ如何使用拦截器](https://github.com/fudiwei/DotNetCore.SKIT.FlurlHttpClient/blob/main/docs/README.md)
---

View File

@ -4,7 +4,7 @@
本功能来自于公共组件,请参阅公共组件下的相关文档:
> [《SKIT.FlurlHttpClient FAQ如何指定 JSON 序列化器?》](https://github.com/fudiwei/DotNetCore.SKIT.FlurlHttpClient/blob/main/docs/FAQ_JsonSerializer.md)
> [《SKIT.FlurlHttpClient FAQ如何指定 JSON 序列化器?》](https://github.com/fudiwei/DotNetCore.SKIT.FlurlHttpClient/blob/main/docs/README.md)
---

View File

@ -6,12 +6,12 @@
```csharp
/* 如果是 JSON 格式的通知内容,以 wxa_media_check 事件为例 */
string callbackJson = "{ ... }";
var callbackModel = client.DeserializeEventFromJson<Events.WxaMediaCheckEvent>(callbackJson);
string webhookJson = "{ ... }";
var webhookModel = client.DeserializeEventFromJson<Events.WxaMediaCheckEvent>(webhookJson);
/* 如果是 XML 格式的通知内容,以 text 事件为例 */
string callbackXml = "<xml> ... </xml>";
var callbackModel = client.DeserializeEventFromXml<Events.TextMessageEvent>(callbackXml);
string webhookXml = "<xml> ... </xml>";
var webhookModel = client.DeserializeEventFromXml<Events.TextMessageEvent>(webhookXml);
```
完整的回调通知模型定义可以参考项目目录下的 _src/SKIT.FlurlHttpClient.Wechat.Api/Events_ 目录。
@ -27,21 +27,27 @@ var callbackModel = client.DeserializeEventFromXml<Events.TextMessageEvent>(call
一种是利用 `System.Xml.Linq`
```csharp
XDocument xDoc = XDocument.Parse(callbackXml);
string msgType = xDoc.Root?.Element("MsgType")?.Value?.ToUpper();
string msgType = XDocument.Parse(webhookXml).Root?.Element("MsgType")?.Value?.ToUpper();
switch (msgType)
{
case "TEXT":
{
var webhookModel = client.DeserializeEventFromXml<Events.TextMessageEvent>(webhookXml);
}
break;
// 其他情况略
}
```
另一种是利用本库的扩展方法:
```csharp
WechatApiEvent eventModel = client.DeserializeEventFromXml(callbackXml);
string msgType = eventModel.MessageType?.ToUpper();
string msgType = client.DeserializeEventFromXml(webhookXml).MessageType?.ToUpper();
switch (msgType)
{
case "TEXT":
{
var callbackModel = client.DeserializeEventFromXml<Events.TextMessageEvent>(callbackXml);
var webhookModel = client.DeserializeEventFromXml<Events.TextMessageEvent>(webhookXml);
}
break;
// 其他情况略
@ -65,7 +71,7 @@ var options = new WechatApiClientOptions()
PushToken = "Token",
PushEncodingAESKey = "EncodingAESKey"
};
var client = new WechatApiClient(options);
var client = WechatApiClientBuilder.Create(options).Build();
```
---

View File

@ -16,22 +16,22 @@ var options = new WechatApiClientOptions()
PushToken = "Token",
PushEncodingAESKey = "EncodingAESKey"
};
var client = new WechatApiClient(options);
var client = WechatApiClientBuilder.Create(options).Build();
/* 验证微信服务器 */
bool ret = client.VerifyEventSignatureForEcho(
callbackTimestamp: "微信回调通知中的 timestamp 字段",
callbackNonce: "微信回调通知中的 nonce 字段",
callbackSignature: "微信回调通知中的 signature 字段"
webhookTimestamp: "微信回调通知中的 timestamp 字段",
webhookNonce: "微信回调通知中的 nonce 字段",
webhookSignature: "微信回调通知中的 signature 字段"
);
/* 验证安全模式下 XML 消息的签名 */
bool ret = client.VerifyEventSignatureFromXml(
callbackXml: "微信公众平台发来的通知内容,形如:<xml><Encrypt>...</Encrypt></xml>"
webhookXml: "微信公众平台发来的通知内容,形如:<xml><Encrypt>...</Encrypt></xml>"
);
/* 验证安全模式下 JSON 消息的签名 */
bool ret = client.VerifyEventSignatureFromJson(
callbackJson: "微信公众平台发来的通知内容,形如:{\"Encrypt\":\"...\"}"
webhookJson: "微信公众平台发来的通知内容,形如:{\"Encrypt\":\"...\"}"
);
```

View File

@ -30,10 +30,10 @@ public static class MyFakeClientExtensions
if (request is null) throw new ArgumentNullException(nameof(request));
IFlurlRequest flurlReq = client
.CreateRequest(request, HttpMethod.Post, "my-fake-url")
.CreateFlurlRequest(request, HttpMethod.Post, "my-fake-url")
.SetQueryParam("access_token", request.AccessToken);
return await client.SendRequestWithJsonAsync<MyFakeResponse>(flurlReq, request, cancellationToken);
return await client.SendFlurlRequestAsJsonAsync<MyFakeResponse>(flurlReq, request, cancellationToken);
}
}
```
@ -42,7 +42,7 @@ public static class MyFakeClientExtensions
```csharp
/* 继承 WechatApiEvent 实现自定义的 JSON 格式的回调通知事件 */
public class MyFakeEvent : WechatApiEvent, WechatApiEvent.Serialization.IJsonSerializable
public class MyFakeEvent : WechatApiEvent
{
[Newtonsoft.Json.JsonProperty("my_fake_props")]
[System.Text.Json.Serialization.JsonPropertyName("my_fake_props")]
@ -50,7 +50,7 @@ public class MyFakeEvent : WechatApiEvent, WechatApiEvent.Serialization.IJsonSer
}
/* 继承 WechatApiEvent 实现自定义的 XML 格式的回调通知事件 */
public class MyFakeEvent : WechatApiEvent, WechatApiEvent.Serialization.IXmlSerializable
public class MyFakeEvent : WechatApiEvent
{
[System.Xml.Serialization.XmlElement("my_fake_props")]
public string MyFakeProps { get; set; }

View File

@ -14,6 +14,9 @@
## 快速入门
> [!IMPORTANT]
> 此目录下的文档适用于 v3.x 版本的模块。如果你正在使用 2.x 版本,请移步至 GitHub/Gitee 的已归档分支。
### 安装:
提示:如果你使用 Visual Studio NuGet 管理器图形化界面,请在搜索结果中勾选“**包括预发行版**”。
@ -44,7 +47,7 @@ var options = new WechatApiClientOptions()
MidasOfferIdV2 = "米大师 2.0 相关服务 OfferId不用则不填",
MidasAppKeyV2 = "米大师 2.0 相关服务 AppKey不用则不填"
};
var client = new WechatApiClient(options);
var client = WechatApiClientBuilder.Create(options).Build();
```
### 请求 & 响应:
@ -76,7 +79,7 @@ else
## 基础用法
- [如何快速找到需要调用的 API 模型类名 / 方法名?](./Basic_ModelDefinition.md)
- [如何快速找到需要调用的 API 模型类名 / 方法名?](./Basic_ModelDefinition.md)
- [如何解析回调通知事件?](./Basic_EventDeserialization.md)
@ -84,7 +87,7 @@ else
- [如何解密经过加密处理的开放数据?](./Basic_OpenDataDecryption.md)
- [如何生成 JS-SDK 初始化时所需的参数及签名?](./Basic_Parameters.md)
- [如何生成 JS-SDK 初始化时所需的参数及签名?](./Basic_Parameters.md)
- [如何自定义额外的 API 接口?](./Basic_Extensions.md)
@ -92,7 +95,7 @@ else
## 高级技巧
- [如何在 ASP.NET Core 中与 `IHttpClientFactory` 集成?](./Advanced_IHttpClientFactory.md)
- [如何与 `IHttpClientFactory` 集成?](./Advanced_IHttpClientFactory.md)
- [如何指定 JSON 序列化器?](./Advanced_JsonSerializer.md)

View File

@ -1,10 +1,10 @@
## 如何在 ASP.NET Core 中`IHttpClientFactory` 集成?
## 如何与 `IHttpClientFactory` 集成?
---
本功能来自于公共组件,请参阅公共组件下的相关文档:
> [《SKIT.FlurlHttpClient FAQ如何在 ASP.NET Core 中与 IHttpClientFactory 集成?》](https://github.com/fudiwei/DotNetCore.SKIT.FlurlHttpClient/blob/main/docs/FAQ_IHttpClientFactory.md)
> [《SKIT.FlurlHttpClient FAQ如何与 IHttpClientFactory 集成?》](https://github.com/fudiwei/DotNetCore.SKIT.FlurlHttpClient/blob/main/docs/README.md)
---

View File

@ -4,7 +4,7 @@
本功能来自于公共组件,请参阅公共组件下的相关文档:
> [《SKIT.FlurlHttpClient FAQ如何使用拦截器](https://github.com/fudiwei/DotNetCore.SKIT.FlurlHttpClient/blob/main/docs/FAQ_Interceptor.md)
> [《SKIT.FlurlHttpClient FAQ如何使用拦截器](https://github.com/fudiwei/DotNetCore.SKIT.FlurlHttpClient/blob/main/docs/README.md)
---

View File

@ -4,7 +4,7 @@
本功能来自于公共组件,请参阅公共组件下的相关文档:
> [《SKIT.FlurlHttpClient FAQ如何指定 JSON 序列化器?》](https://github.com/fudiwei/DotNetCore.SKIT.FlurlHttpClient/blob/main/docs/FAQ_JsonSerializer.md)
> [《SKIT.FlurlHttpClient FAQ如何指定 JSON 序列化器?》](https://github.com/fudiwei/DotNetCore.SKIT.FlurlHttpClient/blob/main/docs/README.md)
---

View File

@ -13,6 +13,9 @@
## 快速入门
> [!IMPORTANT]
> 此目录下的文档适用于 v3.x 版本的模块。如果你正在使用 2.x 版本,请移步至 GitHub/Gitee 的已归档分支。
### 安装:
提示:如果你使用 Visual Studio NuGet 管理器图形化界面,请在搜索结果中勾选“**包括预发行版**”。
@ -37,7 +40,7 @@ var options = new WechatOpenAIClientOptions()
Token = "微信智能对话 Token",
EncodingAESKey = "微信智能对话 EncodingAESKey"
};
var client = new WechatOpenAIClient(options);
var client = WechatOpenAIClientBuilder.Create(options).Build();
```
### 请求 & 响应:
@ -71,13 +74,13 @@ else
## 基础用法
- [如何快速找到需要调用的 API 模型类名 / 方法名?](./Basic_ModelDefinition.md)
- [如何快速找到需要调用的 API 模型类名 / 方法名?](./Basic_ModelDefinition.md)
---
## 高级技巧
- [如何在 ASP.NET Core 中与 `IHttpClientFactory` 集成?](./Advanced_IHttpClientFactory.md)
- [如何与 `IHttpClientFactory` 集成?](./Advanced_IHttpClientFactory.md)
- [如何指定 JSON 序列化器?](./Advanced_JsonSerializer.md)

View File

@ -1,14 +1,10 @@
## 如何在 ASP.NET Core 中`IHttpClientFactory` 集成?
## 如何与 `IHttpClientFactory` 集成?
---
本功能来自于公共组件,请参阅公共组件下的相关文档:
> [《SKIT.FlurlHttpClient FAQ如何在 ASP.NET Core 中与 IHttpClientFactory 集成?》](https://github.com/fudiwei/DotNetCore.SKIT.FlurlHttpClient/blob/main/docs/FAQ_IHttpClientFactory.md)
需要注意的是,由于部分微信支付接口需要显式地在构造 `System.Net.Http.HttpMessageHandler` 时指定双向认证的 SSL 证书,按照上文提供的方式自定义 `Flurl.Http.Configuration.DefaultHttpClientFactory` 时,也就必须重写此部分逻辑。
关于这点可以参考本库内置的一个类型,完整的代码请参阅项目目录下的 _src/SKIT.FlurlHttpClient.Wechat.TenpayV2/Settings/HttpClientFactory_ 文件。
> [《SKIT.FlurlHttpClient FAQ如何与 IHttpClientFactory 集成?》](https://github.com/fudiwei/DotNetCore.SKIT.FlurlHttpClient/blob/main/docs/README.md)
---

View File

@ -4,7 +4,7 @@
本功能来自于公共组件,请参阅公共组件下的相关文档:
> [《SKIT.FlurlHttpClient FAQ如何使用拦截器](https://github.com/fudiwei/DotNetCore.SKIT.FlurlHttpClient/blob/main/docs/FAQ_Interceptor.md)
> [《SKIT.FlurlHttpClient FAQ如何使用拦截器](https://github.com/fudiwei/DotNetCore.SKIT.FlurlHttpClient/blob/main/docs/README.md)
---

View File

@ -4,7 +4,7 @@
本功能来自于公共组件,请参阅公共组件下的相关文档:
> [《SKIT.FlurlHttpClient FAQ如何指定 JSON 序列化器?》](https://github.com/fudiwei/DotNetCore.SKIT.FlurlHttpClient/blob/main/docs/FAQ_JsonSerializer.md)
> [《SKIT.FlurlHttpClient FAQ如何指定 JSON 序列化器?》](https://github.com/fudiwei/DotNetCore.SKIT.FlurlHttpClient/blob/main/docs/README.md)
---

View File

@ -10,8 +10,8 @@
```csharp
bool ret = client.VerifyEventSignature(
callbackAuthorization: "微企付回调通知中的 TBEP-Authorization 标头",
callbackBody: "微企付回调通知中请求正文"
webhookAuthorization: "微企付回调通知中的 TBEP-Authorization 标头",
webhookBody: "微企付回调通知中请求正文"
);
```
@ -19,13 +19,12 @@ bool ret = client.VerifyEventSignature(
### 调试验签错误:
由于 `VerifyEventSignature()` 方法内部会 `try-catch` 掉所有异常情况,并直接返回 `false`。为方便开发者在调试阶段排查验签的错误信息,你可以在验证回调通知事件签名时指定接收最后一个 `out` 返回参数,该参数中包含了一些异常的原因和相关堆栈信息。
由于 `VerifyEventSignature()` 方法内部会 `try-catch` 掉所有异常情况,并直接返回 `false`。为方便开发者在调试阶段排查验签的错误信息,你可以在验证回调通知事件签名时指定返回值类型为 `ErroredResult` 而非 `Boolean`,该返回值中包含了一些异常的原因和相关堆栈信息。
```csharp
bool ret = client.VerifyEventSignature(authorization, signature, out Exception error);
if (!ret)
ErroredResult res = client.VerifyEventSignature(authorization, signature);
if (!res.Result)
{
Console.WriteLine(error);
Console.WriteLine(error?.InnerException);
Console.WriteLine(res.Error);
}
```

View File

@ -58,7 +58,7 @@ var options = new WechatTenpayBusinessOptions()
SensitivePropertyEncryptionSM4Key = "SM4 密钥",
SensitivePropertyEncryptionSM4IV = "SM4 偏移量"
};
var client = new WechatTenpayBusinessClient(options);
var client = WechatTenpayBusinessClientBuilder.Create(options).Build();
```
这样,本库会在实际发出请求前自动为你调用 `EncryptRequestSensitiveProperty()` 方法。

View File

@ -38,7 +38,7 @@ var options = new WechatTenpayBusinessClientOptions()
{
AutoDecryptResponseSensitiveProperty = true
};
var client = new WechatTenpayBusinessClient(options);
var client = WechatTenpayBusinessClientBuilder.Create(options).Build();
```
这样,本库会在实际收到响应后自动为你调用 `DecryptResponseSensitiveProperty()` 方法。

View File

@ -25,13 +25,12 @@ bool ret = client.VerifyResponseSignature(response);
### 调试验签错误:
由于 `VerifyResponseSignature()` 方法内部会 `try-catch` 掉所有异常情况,并直接返回 `false`。为方便开发者在调试阶段排查验签的错误信息,你可以在验证响应签名时指定接收最后一个 `out` 返回参数,该参数中包含了一些异常的原因和相关堆栈信息。
由于 `VerifyResponseSignature()` 方法内部会 `try-catch` 掉所有异常情况,并直接返回 `false`。为方便开发者在调试阶段排查验签的错误信息,你可以在验证响应签名时指定返回值类型为 `ErroredResult` 而非 `Boolean`,该返回值中包含了一些异常的原因和相关堆栈信息。
```csharp
bool ret = client.VerifyResponseSignature(response, out Exception error);
if (!ret)
ErroredResult res = client.VerifyResponseSignature(response);
if (!res.Result)
{
Console.WriteLine(error);
Console.WriteLine(error?.InnerException);
Console.WriteLine(res.Error);
}
```

View File

@ -15,6 +15,9 @@
## 快速入门
> [!IMPORTANT]
> 此目录下的文档适用于 v3.x 版本的模块。如果你正在使用 2.x 版本,请移步至 GitHub/Gitee 的已归档分支。
### 安装:
提示:如果你使用 Visual Studio NuGet 管理器图形化界面,请在搜索结果中勾选“**包括预发行版**”。
@ -30,7 +33,6 @@
### 初始化:
```csharp
using SKIT.FlurlHttpClient.Wechat;
using SKIT.FlurlHttpClient.Wechat.TenpayBusiness;
var options = new WechatTenpayBusinessClientOptions()
@ -44,7 +46,7 @@ var options = new WechatTenpayBusinessClientOptions()
TBEPCertificateSerialNumber = "微企付证书序列号",
TBEPCertificatePublicKey = "-----BEGIN PUBLIC KEY-----微企付证书公钥-----END PUBLIC KEY-----"
};
var client = new WechatTenpayBusinessClient(options);
var client = WechatTenpayBusinessClientBuilder.Create(options).Build();
```
### 请求 & 响应:
@ -74,7 +76,7 @@ else
## 基础用法
- [如何快速找到需要调用的 API 模型类名 / 方法名(附完整 API 对照表)?](./Basic_ModelDefinition.md)
- [如何快速找到需要调用的 API 模型类名 / 方法名(附完整 API 对照表)?](./Basic_ModelDefinition.md)
- [如何加密请求中的敏感数据?](./Basic_RequestSensitiveDataEncryption.md)
@ -88,7 +90,7 @@ else
## 高级技巧
- [如何在 ASP.NET Core 中与 `IHttpClientFactory` 集成?](./Advanced_IHttpClientFactory.md)
- [如何与 `IHttpClientFactory` 集成?](./Advanced_IHttpClientFactory.md)
- [如何指定 JSON 序列化器?](./Advanced_JsonSerializer.md)

View File

@ -1,14 +1,14 @@
## 如何在 ASP.NET Core 中`IHttpClientFactory` 集成?
## 如何与 `IHttpClientFactory` 集成?
---
本功能来自于公共组件,请参阅公共组件下的相关文档:
> [《SKIT.FlurlHttpClient FAQ如何在 ASP.NET Core 中与 IHttpClientFactory 集成?》](https://github.com/fudiwei/DotNetCore.SKIT.FlurlHttpClient/blob/main/docs/FAQ_IHttpClientFactory.md)
> [《SKIT.FlurlHttpClient FAQ如何与 IHttpClientFactory 集成?》](https://github.com/fudiwei/DotNetCore.SKIT.FlurlHttpClient/blob/main/docs/README.md)
需要注意的是,由于部分微信支付接口需要显式地在构造 `System.Net.Http.HttpMessageHandler` 时指定双向认证的 SSL 证书,按照上文提供的方式自定义 `Flurl.Http.Configuration.DefaultHttpClientFactory` 时,也就必须重写此部分逻辑。
需要注意的是,由于部分微信支付接口需要显式地在构造 `System.Net.Http.HttpMessageHandler` 时指定双向认证的 SSL 证书,按照上文提供的方式自定义 `System.Net.Http.HttpClient` 时,也就必须重写此部分逻辑。
关于这点可以参考本库内置的一个类型,完整的代码请参阅项目目录下的 _src/SKIT.FlurlHttpClient.Wechat.TenpayV2/Settings/HttpClientFactory_ 文件。
关于这点可以参考本库内置的一个类型,完整的代码请参阅项目目录下的 _src/SKIT.FlurlHttpClient.Wechat.TenpayV2/Settings/WechatpayHttpHandler.cs_ 文件。
---

View File

@ -4,7 +4,7 @@
本功能来自于公共组件,请参阅公共组件下的相关文档:
> [《SKIT.FlurlHttpClient FAQ如何使用拦截器](https://github.com/fudiwei/DotNetCore.SKIT.FlurlHttpClient/blob/main/docs/FAQ_Interceptor.md)
> [《SKIT.FlurlHttpClient FAQ如何使用拦截器](https://github.com/fudiwei/DotNetCore.SKIT.FlurlHttpClient/blob/main/docs/README.md)
---

View File

@ -4,7 +4,7 @@
本功能来自于公共组件,请参阅公共组件下的相关文档:
> [《SKIT.FlurlHttpClient FAQ如何指定 JSON 序列化器?》](https://github.com/fudiwei/DotNetCore.SKIT.FlurlHttpClient/blob/main/docs/FAQ_JsonSerializer.md)
> [《SKIT.FlurlHttpClient FAQ如何指定 JSON 序列化器?》](https://github.com/fudiwei/DotNetCore.SKIT.FlurlHttpClient/blob/main/docs/README.md)
---

View File

@ -12,13 +12,13 @@
```csharp
/* 微信商户平台发来的通知内容 */
string callbackXml = "<xml> ... </xml>";
string webhookXml = "<xml> ... </xml>";
/* 将 XML 反序列化得到通知对象 */
var callbackModel = client.DeserializeEvent(callbackXml);
var webhookModel = client.DeserializeEvent(webhookXml);
/* 解密得到支付通知敏感数据(以退款结果通知为例) */
var callbackEventInfo = client.DecryptEventRequestInfo<Events.RefundEventRequestInfo>(callbackModel);
string outRefundNumber = callbackResource.OutRefundNumber;
string refundId = callbackResource.RefundId;
var webhookEventInfo = client.DecryptEventRequestInfo<Events.RefundEventRequestInfo>(webhookModel);
string outRefundNumber = webhookEventInfo.OutRefundNumber;
string refundId = webhookEventInfo.RefundId;
```
完整的回调通知模型定义可以参考项目目录下的 _src/SKIT.FlurlHttpClient.Wechat.TenpayV2/Events_ 目录。

View File

@ -10,6 +10,6 @@
```csharp
bool ret = client.VerifyEventSignature(
callbackBody: "<xml> 微信回调通知中请求正文 XML 内容 </xml>"
webhookBody: "<xml> 微信回调通知中请求正文 XML 内容 </xml>"
);
```

View File

@ -18,6 +18,9 @@
## 快速入门
> [!IMPORTANT]
> 此目录下的文档适用于 v3.x 版本的模块。如果你正在使用 2.x 版本,请移步至 GitHub/Gitee 的已归档分支。
### 安装:
提示:如果你使用 Visual Studio NuGet 管理器图形化界面,请在搜索结果中勾选“**包括预发行版**”。
@ -33,7 +36,6 @@
### 初始化:
```csharp
using SKIT.FlurlHttpClient.Wechat;
using SKIT.FlurlHttpClient.Wechat.TenpayV2;
var options = new WechatTenpayClientOptions()
@ -43,7 +45,7 @@ var options = new WechatTenpayClientOptions()
MerchantCertificateBytes = File.ReadAllBytes("/微信商户证书文件路径/apiclient_cert.p12"),
MerchantCertificatePassword = "微信商户证书密码,通常是商户号"
};
var client = new WechatTenpayClient(options);
var client = WechatTenpayClientBuilder.Create(options).Build();
```
### 请求 & 响应:
@ -82,7 +84,7 @@ else
## 基础用法
- [如何快速找到需要调用的 API 模型类名 / 方法名(附完整 API 对照表)?](./Basic_ModelDefinition.md)
- [如何快速找到需要调用的 API 模型类名 / 方法名(附完整 API 对照表)?](./Basic_ModelDefinition.md)
- [如何解密回调通知事件中的敏感数据?](./Basic_EventInfoDecryption.md)
@ -94,7 +96,7 @@ else
## 高级技巧
- [如何在 ASP.NET Core 中与 `IHttpClientFactory` 集成?](./Advanced_IHttpClientFactory.md)
- [如何与 `IHttpClientFactory` 集成?](./Advanced_IHttpClientFactory.md)
- [如何指定 JSON 序列化器?](./Advanced_JsonSerializer.md)

View File

@ -1,10 +1,10 @@
## 如何在 ASP.NET Core 中`IHttpClientFactory` 集成?
## 如何与 `IHttpClientFactory` 集成?
---
本功能来自于公共组件,请参阅公共组件下的相关文档:
> [《SKIT.FlurlHttpClient FAQ如何在 ASP.NET Core 中与 IHttpClientFactory 集成?》](https://github.com/fudiwei/DotNetCore.SKIT.FlurlHttpClient/blob/main/docs/FAQ_IHttpClientFactory.md)
> [《SKIT.FlurlHttpClient FAQ如何与 IHttpClientFactory 集成?》](https://github.com/fudiwei/DotNetCore.SKIT.FlurlHttpClient/blob/main/docs/README.md)
---

View File

@ -4,7 +4,7 @@
本功能来自于公共组件,请参阅公共组件下的相关文档:
> [《SKIT.FlurlHttpClient FAQ如何使用拦截器](https://github.com/fudiwei/DotNetCore.SKIT.FlurlHttpClient/blob/main/docs/FAQ_Interceptor.md)
> [《SKIT.FlurlHttpClient FAQ如何使用拦截器](https://github.com/fudiwei/DotNetCore.SKIT.FlurlHttpClient/blob/main/docs/README.md)
---

View File

@ -4,7 +4,7 @@
本功能来自于公共组件,请参阅公共组件下的相关文档:
> [《SKIT.FlurlHttpClient FAQ如何指定 JSON 序列化器?》](https://github.com/fudiwei/DotNetCore.SKIT.FlurlHttpClient/blob/main/docs/FAQ_JsonSerializer.md)
> [《SKIT.FlurlHttpClient FAQ如何指定 JSON 序列化器?》](https://github.com/fudiwei/DotNetCore.SKIT.FlurlHttpClient/blob/main/docs/README.md)
---

View File

@ -26,16 +26,16 @@
```csharp
/* 微信商户平台发来的通知内容 */
string callbackJson = "{ ... }";
string webhookJson = "{ ... }";
/* 将 JSON 反序列化得到通知对象 */
/* 你也可以将 WechatTenpayEvent 类型直接绑定到 MVC 模型上,这样就不再需要手动反序列化 */
var callbackModel = client.DeserializeEvent(callbackJson);
if ("TRANSACTION.SUCCESS".Equals(callbackModel.EventType))
var webhookModel = client.DeserializeEvent(webhookJson);
if ("TRANSACTION.SUCCESS".Equals(webhookModel.EventType))
{
/* 根据事件类型,解密得到支付通知敏感数据 */
var callbackResource = client.DecryptEventResource<Events.TransactionResource>(callbackModel);
string outTradeNumber = callbackResource.OutTradeNumber;
string transactionId = callbackResource.TransactionId;
var webhookResource = client.DecryptEventResource<Events.TransactionResource>(webhookModel);
string outTradeNumber = webhookResource.OutTradeNumber;
string transactionId = webhookResource.TransactionId;
}
```

View File

@ -37,11 +37,11 @@
```csharp
bool ret = client.VerifyEventSignature(
callbackTimestamp: "微信回调通知中的 Wechatpay-Timestamp 标头",
callbackNonce: "微信回调通知中的 Wechatpay-Nonce 标头",
callbackBody: "微信回调通知中请求正文",
callbackSignature: "微信回调通知中的 Wechatpay-Signature 标头",
callbackSerialNumber: "微信回调通知中的 Wechatpay-Serial 标头"
webhookTimestamp: "微信回调通知中的 Wechatpay-Timestamp 标头",
webhookNonce: "微信回调通知中的 Wechatpay-Nonce 标头",
webhookBody: "微信回调通知中请求正文",
webhookSignature: "微信回调通知中的 Wechatpay-Signature 标头",
webhookSerialNumber: "微信回调通知中的 Wechatpay-Serial 标头"
);
```
@ -51,14 +51,13 @@ bool ret = client.VerifyEventSignature(
### 调试验签错误:
由于 `VerifyEventSignature()` 方法内部会 `try-catch` 掉所有异常情况,并直接返回 `false`。为方便开发者在调试阶段排查验签的错误信息,你可以在验证回调通知事件签名时指定接收最后一个 `out` 返回参数,该参数中包含了一些异常的原因和相关堆栈信息。
由于 `VerifyEventSignature()` 方法内部会 `try-catch` 掉所有异常情况,并直接返回 `false`。为方便开发者在调试阶段排查验签的错误信息,你可以在验证回调通知事件签名时指定返回值类型为 `ErroredResult` 而非 `Boolean`,该返回值中包含了一些异常的原因和相关堆栈信息。
```csharp
bool ret = client.VerifyEventSignature(timestamp, nonce, body, signature, serialNumber, out Exception error);
if (!ret)
ErroredResult res = client.VerifyEventSignature(timestamp, nonce, body, signature, serialNumber);
if (!res.Result)
{
Console.WriteLine(error);
Console.WriteLine(error?.InnerException);
Console.WriteLine(res.Error);
}
```

View File

@ -30,10 +30,10 @@ public static class MyFakeClientExtensions
if (request is null) throw new ArgumentNullException(nameof(request));
IFlurlRequest flurlReq = client
.CreateRequest(request, HttpMethod.Post, "my-fake-url")
.CreateFlurlRequest(request, HttpMethod.Post, "my-fake-url")
.SetQueryParam("access_token", request.AccessToken);
return await client.SendRequestWithJsonAsync<MyFakeResponse>(flurlReq, request, cancellationToken);
return await client.SendFlurlRequestAsJsonAsync<MyFakeResponse>(flurlReq, request, cancellationToken);
}
}
```

View File

@ -82,7 +82,7 @@ var options = new WechatTenpayClientOptions()
// 其他配置项略
AutoEncryptRequestSensitiveProperty = true
};
var client = new WechatTenpayClient(options);
var client = WechatTenpayClientBuilder.Create(options).Build();
```
这样,本库会在实际发出请求前自动为你调用 `EncryptRequestSensitiveProperty()` 方法。
@ -95,7 +95,7 @@ var client = new WechatTenpayClient(options);
### 通过 `CertificateManager` 管理平台证书信息:
微信商户平台证书需要通过 API 的方式获取、且可能同时存在多个有效证书,本库提供了一个 `CertificateManager` 类型可用于管理证书信息。
微信商户平台证书需要通过 API 的方式获取、且可能同时存在多个有效证书,本库提供了一个 `ICertificateManager` 接口可用于管理证书信息。
你可以在构造得到 `WechatTenpayClient` 对象时指定证书管理器:
@ -106,7 +106,7 @@ var options = new WechatTenpayClientOptions()
// 其他配置项略
PlatformCertificateManager = manager
};
var client = new WechatTenpayClient(options);
var client = WechatTenpayClientBuilder.Create(options).Build();
```
> 注:`InMemoryCertificateManager` 是本库内置的基于内存实现的证书管理器;你也可自行继承并实现一个 `CertificateManager`,例如利用数据库或 Redis 等方式存取证书信息。
@ -142,7 +142,7 @@ client.EncryptRequestSensitiveProperty(request);
```csharp
using StackExchange.Redis;
public class RedisCertificateManager : CertificateManager
public class RedisCertificateManager : ICertificateManager
{
private const string REDIS_KEY_PREFIX = "wxpaypc-";
@ -184,7 +184,7 @@ public class RedisCertificateManager : CertificateManager
};
}
public override IEnumerable<CertificateEntry> AllEntries()
public IEnumerable<CertificateEntry> AllEntries()
{
// 生产环境中不应该使用 Redis KEYS 命令,这里代码仅作参考
// 你可以使用 SCAN + CURSOR 来实现类似功能
@ -203,7 +203,7 @@ public class RedisCertificateManager : CertificateManager
return Array.Empty<CertificateEntry>();
}
public override void AddEntry(CertificateEntry entry)
public void AddEntry(CertificateEntry entry)
{
string key = GenerateRedisKey(serialNumber);
HashEntry[] values = ConvertCertificateEntryToHashEntries(entry);
@ -211,7 +211,7 @@ public class RedisCertificateManager : CertificateManager
Connection.GetDatabase().KeyExpire(key, entry.ExpireTime - DateTimeOffset.Now);
}
public override CertificateEntry? GetEntry(string serialNumber)
public CertificateEntry? GetEntry(string serialNumber)
{
string key = GenerateRedisKey(serialNumber);
HashEntry[] values = Connection.GetDatabase().HashGetAll(key);
@ -223,7 +223,7 @@ public class RedisCertificateManager : CertificateManager
return null;
}
public override bool RemoveEntry(string serialNumber)
public bool RemoveEntry(string serialNumber)
{
string key = GenerateRedisKey(serialNumber);
return Connection.GetDatabase().KeyDelete(key);

View File

@ -45,7 +45,7 @@ var options = new WechatTenpayClientOptions()
{
AutoDecryptResponseSensitiveProperty = true
};
var client = new WechatTenpayClient(options);
var client = WechatTenpayClientBuilder.Create(options).Build();
```
这样,本库会在实际收到响应后自动为你调用 `DecryptResponseSensitiveProperty()` 方法。

View File

@ -60,14 +60,13 @@ bool ret = client.VerifyResponseSignature(response);
### 调试验签错误:
由于 `VerifyResponseSignature()` 方法内部会 `try-catch` 掉所有异常情况,并直接返回 `false`。为方便开发者在调试阶段排查验签的错误信息,你可以在验证响应签名时指定接收最后一个 `out` 返回参数,该参数中包含了一些异常的原因和相关堆栈信息。
由于 `VerifyResponseSignature()` 方法内部会 `try-catch` 掉所有异常情况,并直接返回 `false`。为方便开发者在调试阶段排查验签的错误信息,你可以在验证响应签名时指定返回值类型为 `ErroredResult` 而非 `Boolean`,该返回值中包含了一些异常的原因和相关堆栈信息。
```csharp
bool ret = client.VerifyResponseSignature(response, out Exception error);
if (!ret)
ErroredResult res = client.VerifyResponseSignature(response);
if (!res.Result)
{
Console.WriteLine(error);
Console.WriteLine(error?.InnerException);
Console.WriteLine(res.Error);
}
```

View File

@ -22,7 +22,7 @@ var options = new WechatTenpayClientOptions()
// 其他配置项略
SignScheme = Constants.SignSchemes.WECHATPAY2_SM2_WITH_SM3
};
var client = new WechatTenpayClient(options);
var client = WechatTenpayClientBuilder.Create(options).Build();
```
接着,在获取平台证书时,需指定证书的算法类型:

View File

@ -18,6 +18,9 @@
## 快速入门
> [!IMPORTANT]
> 此目录下的文档适用于 v3.x 版本的模块。如果你正在使用 2.x 版本,请移步至 GitHub/Gitee 的已归档分支。
### 安装:
提示:如果你使用 Visual Studio NuGet 管理器图形化界面,请在搜索结果中勾选“**包括预发行版**”。
@ -33,7 +36,6 @@
### 初始化:
```csharp
using SKIT.FlurlHttpClient.Wechat;
using SKIT.FlurlHttpClient.Wechat.TenpayV3;
using SKIT.FlurlHttpClient.Wechat.TenpayV3.Settings;
@ -46,7 +48,7 @@ var options = new WechatTenpayClientOptions()
MerchantCertificatePrivateKey = "-----BEGIN PRIVATE KEY-----微信商户证书私钥,即 `apiclient_key.pem` 文件内容-----END PRIVATE KEY-----",
PlatformCertificateManager = manager // 平台证书管理器的具体用法请参阅下文的基础用法与加密、验签有关的章节
};
var client = new WechatTenpayClient(options);
var client = WechatTenpayClientBuilder.Create(options).Build();
```
### 请求 & 响应:
@ -88,7 +90,7 @@ else
## 基础用法
- [如何快速找到需要调用的 API 模型类名 / 方法名(附完整 API 对照表)?](./Basic_ModelDefinition.md)
- [如何快速找到需要调用的 API 模型类名 / 方法名(附完整 API 对照表)?](./Basic_ModelDefinition.md)
- [如何查看商户证书序列号?](./Basic_CertificateSerialNumber.md)
@ -102,7 +104,7 @@ else
- [如何验证回调通知事件签名?](./Basic_EventSignatureVerification.md)
- [如何生成客户端JSAPI、App、小程序等所需的参数及二次签名](./Basic_Parameters.md)
- [如何生成客户端JSAPI、App、小程序等所需的参数及二次签名](./Basic_Parameters.md)
- [如何自定义额外的 API 接口?](./Basic_Extensions.md)
@ -112,7 +114,7 @@ else
## 高级技巧
- [如何在 ASP.NET Core 中与 `IHttpClientFactory` 集成?](./Advanced_IHttpClientFactory.md)
- [如何与 `IHttpClientFactory` 集成?](./Advanced_IHttpClientFactory.md)
- [如何指定 JSON 序列化器?](./Advanced_JsonSerializer.md)

View File

@ -1,10 +1,10 @@
## 如何在 ASP.NET Core 中`IHttpClientFactory` 集成?
## 如何与 `IHttpClientFactory` 集成?
---
本功能来自于公共组件,请参阅公共组件下的相关文档:
> [《SKIT.FlurlHttpClient FAQ如何在 ASP.NET Core 中与 IHttpClientFactory 集成?》](https://github.com/fudiwei/DotNetCore.SKIT.FlurlHttpClient/blob/main/docs/FAQ_IHttpClientFactory.md)
> [《SKIT.FlurlHttpClient FAQ如何与 IHttpClientFactory 集成?》](https://github.com/fudiwei/DotNetCore.SKIT.FlurlHttpClient/blob/main/docs/README.md)
---

View File

@ -4,7 +4,7 @@
本功能来自于公共组件,请参阅公共组件下的相关文档:
> [《SKIT.FlurlHttpClient FAQ如何使用拦截器](https://github.com/fudiwei/DotNetCore.SKIT.FlurlHttpClient/blob/main/docs/FAQ_Interceptor.md)
> [《SKIT.FlurlHttpClient FAQ如何使用拦截器](https://github.com/fudiwei/DotNetCore.SKIT.FlurlHttpClient/blob/main/docs/README.md)
---

View File

@ -4,7 +4,7 @@
本功能来自于公共组件,请参阅公共组件下的相关文档:
> [《SKIT.FlurlHttpClient FAQ如何指定 JSON 序列化器?》](https://github.com/fudiwei/DotNetCore.SKIT.FlurlHttpClient/blob/main/docs/FAQ_JsonSerializer.md)
> [《SKIT.FlurlHttpClient FAQ如何指定 JSON 序列化器?》](https://github.com/fudiwei/DotNetCore.SKIT.FlurlHttpClient/blob/main/docs/README.md)
---

View File

@ -6,12 +6,12 @@
```csharp
/* 如果是 JSON 格式的通知内容,以 add_schedule 事件为例 */
string callbackJson = "{ ... }";
var callbackModel = client.DeserializeEventFromJson<Events.AddScheduleEvent>(callbackJson);
string webhookJson = "{ ... }";
var webhookModel = client.DeserializeEventFromJson<Events.AddScheduleEvent>(webhookJson);
/* 如果是 XML 格式的通知内容,以 text 事件为例 */
string callbackXml = "<xml> ... </xml>";
var callbackModel = client.DeserializeEventFromXml<Events.TextMessageEvent>(callbackXml);
string webhookXml = "<xml> ... </xml>";
var webhookModel = client.DeserializeEventFromXml<Events.TextMessageEvent>(webhookXml);
```
完整的回调通知模型定义可以参考项目目录下的 _src/SKIT.FlurlHttpClient.Wechat.Work/Events_ 目录。
@ -25,14 +25,12 @@ var callbackModel = client.DeserializeEventFromXml<Events.TextMessageEvent>(call
这里给出一种解决方案:
```csharp
WechatApiEvent eventModel = client.DeserializeEventFromXml(callbackXml);
string msgType = eventModel.MessageType?.ToUpper();
string msgType = eventModel = client.DeserializeEventFromXml(webhookXml).MessageType?.ToUpper();
switch (msgType)
{
case "TEXT":
{
var callbackModel = client.DeserializeEventFromXml<Events.TextMessageEvent>(callbackXml);
var webhookModel = client.DeserializeEventFromXml<Events.TextMessageEvent>(webhookXml);
}
break;
// 其他情况略
@ -56,7 +54,7 @@ var options = new WechatWorkClientOptions()
PushToken = "Token",
PushEncodingAESKey = "EncodingAESKey"
};
var client = new WechatWorkClient(options);
var client = WechatWorkClientBuilder.Create(options).Build();
```
---

View File

@ -30,10 +30,10 @@ public static class MyFakeClientExtensions
if (request is null) throw new ArgumentNullException(nameof(request));
IFlurlRequest flurlReq = client
.CreateRequest(request, HttpMethod.Post, "my-fake-url")
.CreateFlurlRequest(request, HttpMethod.Post, "my-fake-url")
.SetQueryParam("access_token", request.AccessToken);
return await client.SendRequestWithJsonAsync<MyFakeResponse>(flurlReq, request, cancellationToken);
return await client.SendFlurlRequestAsJsonAsync<MyFakeResponse>(flurlReq, request, cancellationToken);
}
}
```
@ -42,7 +42,7 @@ public static class MyFakeClientExtensions
```csharp
/* 继承 WechatWorkEvent 实现自定义的 JSON 格式的回调通知事件 */
public class MyFakeEvent : WechatWorkEvent, WechatWorkEvent.Types.IJsonSerializable
public class MyFakeEvent : WechatWorkEvent
{
[Newtonsoft.Json.JsonProperty("my_fake_props")]
[System.Text.Json.Serialization.JsonPropertyName("my_fake_props")]
@ -50,7 +50,7 @@ public class MyFakeEvent : WechatWorkEvent, WechatWorkEvent.Types.IJsonSerializa
}
/* 继承 WechatWorkEvent 实现自定义的 XML 格式的回调通知事件 */
public class MyFakeEvent : WechatWorkEvent, WechatWorkEvent.Types.IXmlSerializable
public class MyFakeEvent : WechatWorkEvent
{
[System.Xml.Serialization.XmlElement("my_fake_props")]
public string MyFakeProps { get; set; }

View File

@ -44,9 +44,9 @@
与初始化本库的 HTTP API 客户端的过程类似。
```csharp
using SKIT.FlurlHttpClient.Wechat.Work.SDK.Finance;
using SKIT.FlurlHttpClient.Wechat.Work.SDK.Finance.Models;
using SKIT.FlurlHttpClient.Wechat.Work.SDK.Finance.Settings;
using SKIT.FlurlHttpClient.Wechat.Work.ExtendedSDK.Finance;
using SKIT.FlurlHttpClient.Wechat.Work.ExtendedSDK.Finance.Models;
using SKIT.FlurlHttpClient.Wechat.Work.ExtendedSDK.Finance.Settings;
var manager = new InMemoryEncryptionKeyManager();
manager.AddEntry(new EncryptionKeyEntry(1, "-----BEGIN RSA PRIVATE KEY----- 消息加解密私钥 PKCS#1 PEM 内容 -----END RSA PRIVATE KEY-----"));

View File

@ -16,6 +16,9 @@
## 快速入门
> [!IMPORTANT]
> 此目录下的文档适用于 v3.x 版本的模块。如果你正在使用 2.x 版本,请移步至 GitHub/Gitee 的已归档分支。
### 安装:
提示:如果你使用 Visual Studio NuGet 管理器图形化界面,请在搜索结果中勾选“**包括预发行版**”。
@ -31,7 +34,6 @@
### 初始化:
```csharp
using SKIT.FlurlHttpClient.Wechat;
using SKIT.FlurlHttpClient.Wechat.Work;
var options = new WechatWorkClientOptions()
@ -40,7 +42,7 @@ var options = new WechatWorkClientOptions()
AgentId = "企业微信应用的 AgentId",
AgentSecret = "企业微信应用的 Secret"
};
var client = new WechatWorkClient(options);
var client = WechatWorkClientBuilder.Create(options).Build();
```
### 请求 & 响应:
@ -72,11 +74,11 @@ else
## 基础用法
- [如何快速找到需要调用的 API 模型类名 / 方法名?](./Basic_ModelDefinition.md)
- [如何快速找到需要调用的 API 模型类名 / 方法名?](./Basic_ModelDefinition.md)
- [如何解析回调通知事件?](./Basic_EventDeserialization.md)
- [如何生成 JS-SDK 所需的参数及签名?](./Basic_Parameters.md)
- [如何生成 JS-SDK 所需的参数及签名?](./Basic_Parameters.md)
- [如何接入会话内容存档 C SDK](./Basic_FinanceSDK.md)
@ -86,7 +88,7 @@ else
## 高级技巧
- [如何在 ASP.NET Core 中与 `IHttpClientFactory` 集成?](./Advanced_IHttpClientFactory.md)
- [如何与 `IHttpClientFactory` 集成?](./Advanced_IHttpClientFactory.md)
- [如何指定 JSON 序列化器?](./Advanced_JsonSerializer.md)

View File

@ -1,6 +1,3 @@
using System;
using System.Reflection;
namespace SKIT.FlurlHttpClient.Wechat.TenpayV3
{
/// <summary>

View File

@ -8,10 +8,10 @@ namespace SKIT.FlurlHttpClient.Wechat.Work.ExtendedSDK.Finance
{
/// <summary>
/// <para>异步调用会话内容存档之获取会话记录数据接口。</para>
/// <para>
/// REF: <br/>
/// <![CDATA[ https://developer.work.weixin.qq.com/document/path/91774 ]]>
/// </para>
/// <para>
/// REF: <br/>
/// <![CDATA[ https://developer.work.weixin.qq.com/document/path/91774 ]]>
/// </para>
/// </summary>
/// <param name="request"></param>
/// <param name="cancellationToken"></param>
@ -20,10 +20,10 @@ namespace SKIT.FlurlHttpClient.Wechat.Work.ExtendedSDK.Finance
/// <summary>
/// <para>异步调用会话内容存档之解密会话记录数据接口。</para>
/// <para>
/// REF: <br/>
/// <![CDATA[ https://developer.work.weixin.qq.com/document/path/91774 ]]>
/// </para>
/// <para>
/// REF: <br/>
/// <![CDATA[ https://developer.work.weixin.qq.com/document/path/91774 ]]>
/// </para>
/// </summary>
/// <param name="request"></param>
/// <param name="cancellationToken"></param>
@ -32,10 +32,10 @@ namespace SKIT.FlurlHttpClient.Wechat.Work.ExtendedSDK.Finance
/// <summary>
/// <para>异步调用会话内容存档之获取媒体文件分片接口。</para>
/// <para>
/// REF: <br/>
/// <![CDATA[ https://developer.work.weixin.qq.com/document/path/91774 ]]>
/// </para>
/// <para>
/// REF: <br/>
/// <![CDATA[ https://developer.work.weixin.qq.com/document/path/91774 ]]>
/// </para>
/// </summary>
/// <param name="request"></param>
/// <param name="cancellationToken"></param>
@ -44,10 +44,10 @@ namespace SKIT.FlurlHttpClient.Wechat.Work.ExtendedSDK.Finance
/// <summary>
/// <para>异步调用会话内容存档之获取媒体文件接口。</para>
/// <para>
/// REF: <br/>
/// <![CDATA[ https://developer.work.weixin.qq.com/document/path/91774 ]]>
/// </para>
/// <para>
/// REF: <br/>
/// <![CDATA[ https://developer.work.weixin.qq.com/document/path/91774 ]]>
/// </para>
/// </summary>
/// <param name="request"></param>
/// <param name="cancellationToken"></param>