diff --git a/README.md b/README.md index 205cf771..c76ce897 100644 --- a/README.md +++ b/README.md @@ -27,6 +27,8 @@ - 强类型接口模型。 +- 提供拦截器功能。 + - 完整、完善、完全的微信 API 封装。 --- diff --git a/docs/WechatAds/Advanced_IHttpClientFactory.md b/docs/WechatAds/Advanced_IHttpClientFactory.md new file mode 100644 index 00000000..96caa5b9 --- /dev/null +++ b/docs/WechatAds/Advanced_IHttpClientFactory.md @@ -0,0 +1,5 @@ +### 如何在 ASP.NET Core 中与 `IHttpClientFactory` 集成? + +--- + +`IHttpClientFactory` 在本库下的用法与在 [SKIT.FlurlHttpClient.Wechat.Api](../WechatApi/README.md) 模块下的用法类似,请参阅[相关文档](../WechatApi/Advanced_IHttpClientFactory.md)。 diff --git a/docs/WechatAds/Advanced_Interceptor.md b/docs/WechatAds/Advanced_Interceptor.md new file mode 100644 index 00000000..7fad52b3 --- /dev/null +++ b/docs/WechatAds/Advanced_Interceptor.md @@ -0,0 +1,7 @@ +### 如何使用拦截器? + +--- + +拦截器在本库下的用法与在 [SKIT.FlurlHttpClient.Wechat.Api](../WechatApi/README.md) 模块下的用法类似,请参阅[相关文档](../WechatApi/Advanced_Interceptor.md)。 + +本库内置了一个用于请求时自动生成服务商身份令牌(即 AgencyToken)的拦截器。 diff --git a/docs/WechatAds/Advanced_JsonSerializer.md b/docs/WechatAds/Advanced_JsonSerializer.md new file mode 100644 index 00000000..cb9d23af --- /dev/null +++ b/docs/WechatAds/Advanced_JsonSerializer.md @@ -0,0 +1,5 @@ +### 如何指定 JSON 序列化器? + +--- + +JSON 序列化器在本库下的用法与在 [SKIT.FlurlHttpClient.Wechat.Api](../WechatApi/README.md) 模块下的用法类似,请参阅[相关文档](../WechatApi/Advanced_JsonSerializer.md)。 diff --git a/docs/WechatAds/README.md b/docs/WechatAds/README.md index 231c6dba..902eb973 100644 --- a/docs/WechatAds/README.md +++ b/docs/WechatAds/README.md @@ -89,4 +89,10 @@ var response = await client.ExecuteCampaignsAddAsync(request); - [如何快速找到需要调用的 API 模型类名 / 方法名?](./Advanced_ModelDefinition.md) +- [如何在 ASP.NET Core 中与 `IHttpClientFactory` 集成?](./Advanced_IHttpClientFactory.md) + +- [如何指定 JSON 序列化器?](./Advanced_JsonSerializer.md) + +- [如何使用拦截器?](./Advanced_Interceptor.md) + - [如何获取接口调用凭据(即 AccessToken)?](./Advanced_AccessToken.md) diff --git a/docs/WechatApi/Advanced_Interceptor.md b/docs/WechatApi/Advanced_Interceptor.md new file mode 100644 index 00000000..a927a5d9 --- /dev/null +++ b/docs/WechatApi/Advanced_Interceptor.md @@ -0,0 +1,39 @@ +### 如何使用拦截器? + +--- + +拦截器是一种可以监视或重写请求调用的强大机制。下面给出一个用于记录传出请求和传入响应的拦截器简单示例: + +```csharp +public class LoggingInterceptor : WechatHttpCallInterceptor +{ + private readonly ILogger _logger; + + public WechatAdsAgencyTokenInterceptor(ILogger logger) + { + _logger = logger; + } + + public override Task BeforeCallAsync(FlurlCall flurlCall) + { + logger.LogInformation($"Sending request to {flurlCall.Request.Url} on {DateTimeOffset.Now}."); + return Task.CompletedTask; + } + + public override Task AfterCallAsync(FlurlCall flurlCall) + { + logger.LogInformation($"Received response in {flurlCall.Duration.Value.TotalMilliseconds}ms."); + return Task.CompletedTask; + } +} +``` + +示例代码中的 `FlurlCall` 对象,是 `Flurl.Http` 的内置类型,有关该类型的更进一步的说明,请自行阅读相关文档。 + +你可以在构造得到 `WechatApiClient` 对象后,将拦截器注入到该客户端中: + +```csharp +client.Interceptors.Add(new LoggingInterceptor(loggerFactory.CreateLogger())); +``` + +拦截器的工作方式类似于洋葱模型。对于请求拦截器而言,将按照添加时的顺序依次执行;对于响应拦截器而言,将按照添加时的顺序逆序依次执行。 diff --git a/docs/WechatApi/Advanced_JsonSerializer.md b/docs/WechatApi/Advanced_JsonSerializer.md index 705ca8f3..e9cd6153 100644 --- a/docs/WechatApi/Advanced_JsonSerializer.md +++ b/docs/WechatApi/Advanced_JsonSerializer.md @@ -8,7 +8,7 @@ 默认情况下,本库使用 `System.Text.Json` 作为 JSON 序列化器。 -如果你更习惯于 `Newtonsoft.Json`,那么你可以在构造得到 `WechatTenpayClient` 对象后: +如果你更习惯于 `Newtonsoft.Json`,那么你可以在构造得到 `WechatApiClient` 对象后: ```csharp client.Configure(settings => diff --git a/docs/WechatApi/README.md b/docs/WechatApi/README.md index 3373f4c0..cae89132 100644 --- a/docs/WechatApi/README.md +++ b/docs/WechatApi/README.md @@ -4,7 +4,7 @@ [![NuGet Download](https://img.shields.io/nuget/dt/SKIT.FlurlHttpClient.Wechat.Api.svg?sanitize=true)](https://www.nuget.org/packages/SKIT.FlurlHttpClient.Wechat.Api) [![GitHub License](https://img.shields.io/github/license/fudiwei/DotNetCore.SKIT.FlurlHttpClient.Wechat)](https://github.com/fudiwei/DotNetCore.SKIT.FlurlHttpClient.Wechat/blob/main/LICENSE) -基于 `Flurl.Http` 的[微信公众平台]((https://mp.weixin.qq.com/)) & [微信开放平台]((https://open.weixin.qq.com/)) API 客户端。 +基于 `Flurl.Http` 的[微信公众平台](<(https://mp.weixin.qq.com/)>) & [微信开放平台](<(https://open.weixin.qq.com/)>) API 客户端。 --- @@ -161,6 +161,8 @@ var response = await client.ExecuteCgibinUserInfoAsync(request); - [如何指定 JSON 序列化器?](./Advanced_JsonSerializer.md) +- [如何使用拦截器?](./Advanced_Interceptor.md) + - [如何解析回调通知事件?](./Advanced_EventDataDeserialization.md) - [如何生成 JS-SDK 初始化时所需的参数及签名?](./Advanced_JSSDK.md) diff --git a/docs/WechatTenpayV3/Advanced_IHttpClientFactory.md b/docs/WechatTenpayV3/Advanced_IHttpClientFactory.md index a0b6024a..96caa5b9 100644 --- a/docs/WechatTenpayV3/Advanced_IHttpClientFactory.md +++ b/docs/WechatTenpayV3/Advanced_IHttpClientFactory.md @@ -2,67 +2,4 @@ --- -> 请先自行阅读: -> -> [《Microsoft Docs - 使用 IHttpClientFactory 实现复原 HTTP 请求》](https://docs.microsoft.com/zh-cn/dotnet/architecture/microservices/implement-resilient-applications/use-httpclientfactory-to-implement-resilient-http-requests) -> -> [《Microsoft Docs - 在 ASP.NET Core 中使用 IHttpClientFactory 发出 HTTP 请求》](https://docs.microsoft.com/zh-cn/aspnet/core/fundamentals/http-requests#httpclient-and-lifetime-management) -> -> [《Microsoft Docs - .NET Core 2.1 的新增功能:套接字改进》](https://docs.microsoft.com/zh-CN/dotnet/core/whats-new/dotnet-core-2-1#sockets-improvements) - -当你的项目是运行在 ASP.NET Core 2.1 或更高版本的平台时,CLR 已经提供了全新的底层套接字实现,无需你手动干预 `HttpClient` 的生命周期。 - -如果你想手动管理 `HttpClient`,那么可以参考下面基于 DI/IoC 的代码实现: - -```csharp -using Flurl.Http; -using Flurl.Http.Configuration; -using Microsoft.Extensions.Options; -using SKIT.FlurlHttpClient.Wechat.TenpayV3; -using SKIT.FlurlHttpClient.Wechat.TenpayV3.Models; - -public class WechatTenpayClientFactory -{ - internal class DelegatingFlurlClientFactory : IFlurlClientFactory - { - private readonly System.Net.Http.IHttpClientFactory _httpClientFactory; - - public DelegatingFlurlClientFactory(System.Net.Http.IHttpClientFactory httpClientFactory) - { - _httpClientFactory = httpClientFactory ?? throw new ArgumentNullException(nameof(httpClientFactory)); - } - - public Flurl.Http.IFlurlClient Get(Flurl.Url url) - { - return new FlurlClient(_httpClientFactory.CreateClient(url.ToUri())); - } - - public void Dispose() - { - // Do Nothing - } - } - - private readonly System.Net.Http.IHttpClientFactory _httpClientFactory; - private readonly IOptions _wechatTenpayClientOptions; - - public WechatTenpayClientFactory( - System.Net.Http.IHttpClientFactory httpClientFactory, - IOptions wechatTenpayClientOptions) - { - _httpClientFactory = httpClientFactory ?? throw new ArgumentNullException(nameof(httpClientFactory)); - _wechatTenpayClientOptions = wechatTenpayClientOptions ?? throw new ArgumentNullException(nameof(wechatTenpayClientOptions)); - - Flurl.Http.FlurlHttp.GlobalSettings.FlurlClientFactory = new DelegatingFlurlClientFactory(_httpClientFactory); - } - - public WechatTenpayClient CreateClient() - { - return new WechatTenpayClient(_wechatTenpayClientOptions.Value); - } -} -``` - -需要强调的是,虽然 `WechatTenpayClient` 实现了 `System.IDisposable` 接口,但你不应该在 DI/IoC 中手动释放它,而是应该交给 IoC 容器自动管理它。 - -此外你应注意,`System.Net.Http.IHttpClientFactory` 与 `Flurl.Http.Configuration.IHttpClientFactory` 是两个不同的类型,[使用时请加以区分](https://flurl.dev/docs/configuration/#httpclientfactory)。 +`IHttpClientFactory` 在本库下的用法与在 [SKIT.FlurlHttpClient.Wechat.Api](../WechatApi/README.md) 模块下的用法类似,请参阅[相关文档](../WechatApi/Advanced_IHttpClientFactory.md)。 diff --git a/docs/WechatTenpayV3/Advanced_Interceptor.md b/docs/WechatTenpayV3/Advanced_Interceptor.md new file mode 100644 index 00000000..ad43a34f --- /dev/null +++ b/docs/WechatTenpayV3/Advanced_Interceptor.md @@ -0,0 +1,7 @@ +### 如何使用拦截器? + +--- + +拦截器在本库下的用法与在 [SKIT.FlurlHttpClient.Wechat.Api](../WechatApi/README.md) 模块下的用法类似,请参阅[相关文档](../WechatApi/Advanced_Interceptor.md)。 + +本库内置了一个用于请求时自动生成签名的拦截器。 diff --git a/docs/WechatTenpayV3/Advanced_JsonSerializer.md b/docs/WechatTenpayV3/Advanced_JsonSerializer.md index 705ca8f3..0e640491 100644 --- a/docs/WechatTenpayV3/Advanced_JsonSerializer.md +++ b/docs/WechatTenpayV3/Advanced_JsonSerializer.md @@ -2,45 +2,4 @@ --- -> 请先自行阅读: -> -> [《Microsoft Docs - .NET 中的 JSON 序列化和反序列化(封送和拆收)》](https://docs.microsoft.com/zh-cn/dotnet/standard/serialization/system-text-json-overview) - -默认情况下,本库使用 `System.Text.Json` 作为 JSON 序列化器。 - -如果你更习惯于 `Newtonsoft.Json`,那么你可以在构造得到 `WechatTenpayClient` 对象后: - -```csharp -client.Configure(settings => -{ - settings.JsonSerializer = new FlurlNewtonsoftJsonSerializer(); -}); -``` - -此外,如果你希望调整一些序列化器的配置项,那么可以: - -```csharp -using System.Text.Json; -using SKIT.FlurlHttpClient.Wechat; - -client.Configure(settings => -{ - var jsonOptions = FlurlSystemTextJsonSerializer.GetDefaultSerializerOptions(); - jsonOptions.WriteIndented = true; - settings.JsonSerializer = new FlurlSystemTextJsonSerializer(jsonOptions); -}); -``` - -使用 `Newtonsoft.Json` 时也是同样的: - -```csharp -using Newtonsoft.Json; -using SKIT.FlurlHttpClient.Wechat; - -client.Configure(settings => -{ - var jsonSettings = FlurlNewtonsoftJsonSerializer.GetDefaultSerializerSettings(); - jsonSettings.Formatting = Formatting.Indented; - settings.JsonSerializer = new FlurlNewtonsoftJsonSerializer(jsonSettings); -}); -``` +JSON 序列化器在本库下的用法与在 [SKIT.FlurlHttpClient.Wechat.Api](../WechatApi/README.md) 模块下的用法类似,请参阅[相关文档](../WechatApi/Advanced_JsonSerializer.md)。 \ No newline at end of file diff --git a/docs/WechatTenpayV3/README.md b/docs/WechatTenpayV3/README.md index 50d2de41..950b42ec 100644 --- a/docs/WechatTenpayV3/README.md +++ b/docs/WechatTenpayV3/README.md @@ -127,6 +127,8 @@ var response = await client.ExecuteCreatePayTransactionJsapiAsync(request); - [如何指定 JSON 序列化器?](./Advanced_JsonSerializer.md) +- [如何使用拦截器?](./Advanced_Interceptor.md) + - [如何解密响应中的敏感数据?](./Advanced_ResponseDataDecryption.md) - [如何解密回调通知事件中的敏感数据?](./Advanced_EventDataDecryption.md) diff --git a/docs/WechatWork/Advanced_IHttpClientFactory.md b/docs/WechatWork/Advanced_IHttpClientFactory.md index 6c8f5987..96caa5b9 100644 --- a/docs/WechatWork/Advanced_IHttpClientFactory.md +++ b/docs/WechatWork/Advanced_IHttpClientFactory.md @@ -2,67 +2,4 @@ --- -> 请参阅: -> -> [《Microsoft Docs - 使用 IHttpClientFactory 实现复原 HTTP 请求》](https://docs.microsoft.com/zh-cn/dotnet/architecture/microservices/implement-resilient-applications/use-httpclientfactory-to-implement-resilient-http-requests) -> -> [《Microsoft Docs - 在 ASP.NET Core 中使用 IHttpClientFactory 发出 HTTP 请求》](https://docs.microsoft.com/zh-cn/aspnet/core/fundamentals/http-requests#httpclient-and-lifetime-management) -> -> [《Microsoft Docs - .NET Core 2.1 的新增功能:套接字改进》](https://docs.microsoft.com/zh-CN/dotnet/core/whats-new/dotnet-core-2-1#sockets-improvements) - -当你的项目是运行在 ASP.NET Core 2.1 或更高版本的平台时,CLR 已经提供了全新的底层套接字实现,无需你手动干预 `HttpClient` 的生命周期。 - -如果你想手动管理 `HttpClient`,那么可以参考下面基于 DI/IoC 的代码实现: - -```csharp -using Flurl.Http; -using Flurl.Http.Configuration; -using Microsoft.Extensions.Options; -using SKIT.FlurlHttpClient.Wechat.Work; -using SKIT.FlurlHttpClient.Wechat.Work.Models; - -public class WechatApiClientFactory -{ - internal class DelegatingFlurlClientFactory : IFlurlClientFactory - { - private readonly System.Net.Http.IHttpClientFactory _httpClientFactory; - - public DelegatingFlurlClientFactory(System.Net.Http.IHttpClientFactory httpClientFactory) - { - _httpClientFactory = httpClientFactory ?? throw new ArgumentNullException(nameof(httpClientFactory)); - } - - public Flurl.Http.IFlurlClient Get(Flurl.Url url) - { - return new FlurlClient(_httpClientFactory.CreateClient(url.ToUri())); - } - - public void Dispose() - { - // Do Nothing - } - } - - private readonly System.Net.Http.IHttpClientFactory _httpClientFactory; - private readonly IOptions _wechatApiClientOptions; - - public WechatApiClientFactory( - System.Net.Http.IHttpClientFactory httpClientFactory, - IOptions wechatApiClientOptions) - { - _httpClientFactory = httpClientFactory ?? throw new ArgumentNullException(nameof(httpClientFactory)); - _wechatApiClientOptions = wechatApiClientOptions ?? throw new ArgumentNullException(nameof(wechatApiClientOptions)); - - Flurl.Http.FlurlHttp.GlobalSettings.FlurlClientFactory = new DelegatingFlurlClientFactory(_httpClientFactory); - } - - public WechatApiClient CreateClient() - { - return new WechatApiClient(_wechatApiClientOptions.Value); - } -} -``` - -需要强调的是,虽然 `WechatApiClient` 实现了 `System.IDisposable` 接口,但你不应该在 DI/IoC 中手动释放它,而是应该交给 IoC 容器自动管理它。 - -此外你应注意,`System.Net.Http.IHttpClientFactory` 与 `Flurl.Http.Configuration.IHttpClientFactory` 是两个不同的类型,[使用时请加以区分](https://flurl.dev/docs/configuration/#httpclientfactory)。 +`IHttpClientFactory` 在本库下的用法与在 [SKIT.FlurlHttpClient.Wechat.Api](../WechatApi/README.md) 模块下的用法类似,请参阅[相关文档](../WechatApi/Advanced_IHttpClientFactory.md)。 diff --git a/docs/WechatWork/Advanced_Interceptor.md b/docs/WechatWork/Advanced_Interceptor.md new file mode 100644 index 00000000..7e885506 --- /dev/null +++ b/docs/WechatWork/Advanced_Interceptor.md @@ -0,0 +1,5 @@ +### 如何使用拦截器? + +--- + +拦截器在本库下的用法与在 [SKIT.FlurlHttpClient.Wechat.Api](../WechatApi/README.md) 模块下的用法类似,请参阅[相关文档](../WechatApi/Advanced_Interceptor.md)。 diff --git a/docs/WechatWork/Advanced_JsonSerializer.md b/docs/WechatWork/Advanced_JsonSerializer.md index 705ca8f3..cb9d23af 100644 --- a/docs/WechatWork/Advanced_JsonSerializer.md +++ b/docs/WechatWork/Advanced_JsonSerializer.md @@ -2,45 +2,4 @@ --- -> 请先自行阅读: -> -> [《Microsoft Docs - .NET 中的 JSON 序列化和反序列化(封送和拆收)》](https://docs.microsoft.com/zh-cn/dotnet/standard/serialization/system-text-json-overview) - -默认情况下,本库使用 `System.Text.Json` 作为 JSON 序列化器。 - -如果你更习惯于 `Newtonsoft.Json`,那么你可以在构造得到 `WechatTenpayClient` 对象后: - -```csharp -client.Configure(settings => -{ - settings.JsonSerializer = new FlurlNewtonsoftJsonSerializer(); -}); -``` - -此外,如果你希望调整一些序列化器的配置项,那么可以: - -```csharp -using System.Text.Json; -using SKIT.FlurlHttpClient.Wechat; - -client.Configure(settings => -{ - var jsonOptions = FlurlSystemTextJsonSerializer.GetDefaultSerializerOptions(); - jsonOptions.WriteIndented = true; - settings.JsonSerializer = new FlurlSystemTextJsonSerializer(jsonOptions); -}); -``` - -使用 `Newtonsoft.Json` 时也是同样的: - -```csharp -using Newtonsoft.Json; -using SKIT.FlurlHttpClient.Wechat; - -client.Configure(settings => -{ - var jsonSettings = FlurlNewtonsoftJsonSerializer.GetDefaultSerializerSettings(); - jsonSettings.Formatting = Formatting.Indented; - settings.JsonSerializer = new FlurlNewtonsoftJsonSerializer(jsonSettings); -}); -``` +JSON 序列化器在本库下的用法与在 [SKIT.FlurlHttpClient.Wechat.Api](../WechatApi/README.md) 模块下的用法类似,请参阅[相关文档](../WechatApi/Advanced_JsonSerializer.md)。 diff --git a/docs/WechatWork/README.md b/docs/WechatWork/README.md index 2140c3ad..1af719f6 100644 --- a/docs/WechatWork/README.md +++ b/docs/WechatWork/README.md @@ -140,6 +140,8 @@ var response = await client.ExecuteCgibinUserGetAsync(request); - [如何指定 JSON 序列化器?](./Advanced_JsonSerializer.md) +- [如何使用拦截器?](./Advanced_Interceptor.md) + - [如何解析回调通知事件?](./Advanced_EventDataDeserialization.md) - [如何生成 JS-SDK 初始化时所需的参数及签名?](./Advanced_JSSDK.md)