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
8cf032f25a
commit
c774af7466
@ -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)
|
||||
|
||||
---
|
||||
|
||||
|
@ -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)
|
||||
|
||||
---
|
||||
|
||||
|
@ -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)
|
||||
|
||||
---
|
||||
|
||||
|
@ -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)
|
||||
|
||||
|
@ -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)
|
||||
|
||||
---
|
||||
|
||||
|
@ -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)
|
||||
|
||||
---
|
||||
|
||||
|
@ -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)
|
||||
|
||||
---
|
||||
|
||||
|
@ -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();
|
||||
```
|
||||
|
||||
---
|
||||
|
@ -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\":\"...\"}"
|
||||
);
|
||||
```
|
||||
|
@ -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; }
|
||||
|
@ -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)
|
||||
|
||||
|
@ -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)
|
||||
|
||||
---
|
||||
|
||||
|
@ -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)
|
||||
|
||||
---
|
||||
|
||||
|
@ -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)
|
||||
|
||||
---
|
||||
|
||||
|
@ -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)
|
||||
|
||||
|
@ -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)
|
||||
|
||||
---
|
||||
|
||||
|
@ -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)
|
||||
|
||||
---
|
||||
|
||||
|
@ -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)
|
||||
|
||||
---
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
```
|
||||
|
@ -58,7 +58,7 @@ var options = new WechatTenpayBusinessOptions()
|
||||
SensitivePropertyEncryptionSM4Key = "SM4 密钥",
|
||||
SensitivePropertyEncryptionSM4IV = "SM4 偏移量"
|
||||
};
|
||||
var client = new WechatTenpayBusinessClient(options);
|
||||
var client = WechatTenpayBusinessClientBuilder.Create(options).Build();
|
||||
```
|
||||
|
||||
这样,本库会在实际发出请求前自动为你调用 `EncryptRequestSensitiveProperty()` 方法。
|
||||
|
@ -38,7 +38,7 @@ var options = new WechatTenpayBusinessClientOptions()
|
||||
{
|
||||
AutoDecryptResponseSensitiveProperty = true
|
||||
};
|
||||
var client = new WechatTenpayBusinessClient(options);
|
||||
var client = WechatTenpayBusinessClientBuilder.Create(options).Build();
|
||||
```
|
||||
|
||||
这样,本库会在实际收到响应后自动为你调用 `DecryptResponseSensitiveProperty()` 方法。
|
||||
|
@ -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);
|
||||
}
|
||||
```
|
||||
|
@ -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)
|
||||
|
||||
|
@ -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_ 文件。
|
||||
|
||||
---
|
||||
|
||||
|
@ -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)
|
||||
|
||||
---
|
||||
|
||||
|
@ -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)
|
||||
|
||||
---
|
||||
|
||||
|
@ -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_ 目录。
|
||||
|
@ -10,6 +10,6 @@
|
||||
|
||||
```csharp
|
||||
bool ret = client.VerifyEventSignature(
|
||||
callbackBody: "<xml> 微信回调通知中请求正文 XML 内容 </xml>"
|
||||
webhookBody: "<xml> 微信回调通知中请求正文 XML 内容 </xml>"
|
||||
);
|
||||
```
|
||||
|
@ -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)
|
||||
|
||||
|
@ -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)
|
||||
|
||||
---
|
||||
|
||||
|
@ -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)
|
||||
|
||||
---
|
||||
|
||||
|
@ -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)
|
||||
|
||||
---
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
```
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
```
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
@ -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);
|
||||
|
@ -45,7 +45,7 @@ var options = new WechatTenpayClientOptions()
|
||||
{
|
||||
AutoDecryptResponseSensitiveProperty = true
|
||||
};
|
||||
var client = new WechatTenpayClient(options);
|
||||
var client = WechatTenpayClientBuilder.Create(options).Build();
|
||||
```
|
||||
|
||||
这样,本库会在实际收到响应后自动为你调用 `DecryptResponseSensitiveProperty()` 方法。
|
||||
|
@ -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);
|
||||
}
|
||||
```
|
||||
|
||||
|
@ -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();
|
||||
```
|
||||
|
||||
接着,在获取平台证书时,需指定证书的算法类型:
|
||||
|
@ -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)
|
||||
|
||||
|
@ -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)
|
||||
|
||||
---
|
||||
|
||||
|
@ -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)
|
||||
|
||||
---
|
||||
|
||||
|
@ -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)
|
||||
|
||||
---
|
||||
|
||||
|
@ -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();
|
||||
```
|
||||
|
||||
---
|
||||
|
@ -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; }
|
||||
|
@ -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-----"));
|
||||
|
@ -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)
|
||||
|
||||
|
@ -1,6 +1,3 @@
|
||||
using System;
|
||||
using System.Reflection;
|
||||
|
||||
namespace SKIT.FlurlHttpClient.Wechat.TenpayV3
|
||||
{
|
||||
/// <summary>
|
||||
|
@ -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>
|
||||
|
Loading…
Reference in New Issue
Block a user