mirror of
https://gitee.com/fudiwei/DotNetCore.SKIT.FlurlHttpClient.Wechat.git
synced 2025-04-05 08:37:22 +08:00
feat: 移除基础依赖库,升级公共组件,并适配 .NET 6.0
This commit is contained in:
parent
b11f6bb73b
commit
acea1b477c
@ -1,4 +1,7 @@
|
||||
[*.cs]
|
||||
|
||||
# CS1570: XML 注释出现 XML 格式错误
|
||||
dotnet_diagnostic.CS1570.severity = none
|
||||
|
||||
# CS1591: 缺少对公共可见类型或成员的 XML 注释
|
||||
dotnet_diagnostic.CS1591.severity = suggestion
|
||||
|
@ -124,7 +124,6 @@
|
||||
|
||||
- **必须**:提交记录中的 `<scope>`,可取值为:
|
||||
|
||||
- _core_:关于 `SKIT.FlurlHttpClient.Wechat` 项目的变化;
|
||||
- _wxapi_:关于 `SKIT.FlurlHttpClient.Wechat.Api` 项目的变化;
|
||||
- _tenpayv3_:关于 `SKIT.FlurlHttpClient.Wechat.TenpayV3` 项目的变化;
|
||||
- _work_:关于 `SKIT.FlurlHttpClient.Wechat.Work` 项目的变化;
|
||||
|
@ -17,7 +17,7 @@
|
||||
|
||||
- 基于 `Flurl.Http`,可与 `IHttpClientFactory` 集成。
|
||||
|
||||
- 支持 .NET Framework 4.6.1+、.NET Standard 2.0+、.NET Core 2.0+、.NET 5。
|
||||
- 支持 .NET Framework 4.6.1+、.NET Standard 2.0+、.NET Core 2.0+、.NET 5、.NET 6。
|
||||
|
||||
- 支持 Windows / Linux / macOS 多平台部署。
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Version 16
|
||||
VisualStudioVersion = 16.0.31112.23
|
||||
# Visual Studio Version 17
|
||||
VisualStudioVersion = 17.0.31903.59
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{D5D590C3-7794-4BEB-9BC4-68EE4E09E064}"
|
||||
ProjectSection(SolutionItems) = preProject
|
||||
@ -10,8 +10,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{3E34ADB9-1F52-4C96-9A42-DE782DE1AAA3}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SKIT.FlurlHttpClient.Wechat", "src\SKIT.FlurlHttpClient.Wechat\SKIT.FlurlHttpClient.Wechat.csproj", "{63F7116F-320A-4CD8-9B84-2C675412F70F}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SKIT.FlurlHttpClient.Wechat.Api", "src\SKIT.FlurlHttpClient.Wechat.Api\SKIT.FlurlHttpClient.Wechat.Api.csproj", "{082C1F69-7932-473F-A700-49584371BE8C}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SKIT.FlurlHttpClient.Wechat.TenpayV3", "src\SKIT.FlurlHttpClient.Wechat.TenpayV3\SKIT.FlurlHttpClient.Wechat.TenpayV3.csproj", "{6FE502D4-C43D-49C9-9E57-D1EE566FD1C3}"
|
||||
@ -20,7 +18,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SKIT.FlurlHttpClient.Wechat
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SKIT.FlurlHttpClient.Wechat.Ads", "src\SKIT.FlurlHttpClient.Wechat.Ads\SKIT.FlurlHttpClient.Wechat.Ads.csproj", "{7F155EFB-152F-4798-9984-99102B21D2F8}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SKIT.FlurlHttpClient.Wechat.OpenAI", "src\SKIT.FlurlHttpClient.Wechat.OpenAI\SKIT.FlurlHttpClient.Wechat.OpenAI.csproj", "{AAE2E9BC-4D0B-4495-8825-DF8C405DB4A0}"
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SKIT.FlurlHttpClient.Wechat.OpenAI", "src\SKIT.FlurlHttpClient.Wechat.OpenAI\SKIT.FlurlHttpClient.Wechat.OpenAI.csproj", "{AAE2E9BC-4D0B-4495-8825-DF8C405DB4A0}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{C95AF531-CF44-44AA-AC90-F4DF9F941674}"
|
||||
EndProject
|
||||
@ -36,7 +34,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SKIT.FlurlHttpClient.Wechat
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SKIT.FlurlHttpClient.Wechat.Ads.UnitTests", "test\SKIT.FlurlHttpClient.Wechat.Ads.UnitTests\SKIT.FlurlHttpClient.Wechat.Ads.UnitTests.csproj", "{561E0BFB-7817-41FE-BAF2-D78817679AC1}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SKIT.FlurlHttpClient.Wechat.OpenAI.UnitTests", "test\SKIT.FlurlHttpClient.Wechat.OpenAI.UnitTests\SKIT.FlurlHttpClient.Wechat.OpenAI.UnitTests.csproj", "{9689135B-44BA-4D55-8663-7C669BAFE066}"
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SKIT.FlurlHttpClient.Wechat.OpenAI.UnitTests", "test\SKIT.FlurlHttpClient.Wechat.OpenAI.UnitTests\SKIT.FlurlHttpClient.Wechat.OpenAI.UnitTests.csproj", "{9689135B-44BA-4D55-8663-7C669BAFE066}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "samples", "samples", "{35C901ED-C234-4A91-9561-AD89B3BB788D}"
|
||||
EndProject
|
||||
@ -50,10 +48,6 @@ Global
|
||||
Release|Any CPU = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{63F7116F-320A-4CD8-9B84-2C675412F70F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{63F7116F-320A-4CD8-9B84-2C675412F70F}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{63F7116F-320A-4CD8-9B84-2C675412F70F}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{63F7116F-320A-4CD8-9B84-2C675412F70F}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{082C1F69-7932-473F-A700-49584371BE8C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{082C1F69-7932-473F-A700-49584371BE8C}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{082C1F69-7932-473F-A700-49584371BE8C}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
@ -70,6 +64,10 @@ Global
|
||||
{7F155EFB-152F-4798-9984-99102B21D2F8}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{7F155EFB-152F-4798-9984-99102B21D2F8}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{7F155EFB-152F-4798-9984-99102B21D2F8}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{AAE2E9BC-4D0B-4495-8825-DF8C405DB4A0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{AAE2E9BC-4D0B-4495-8825-DF8C405DB4A0}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{AAE2E9BC-4D0B-4495-8825-DF8C405DB4A0}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{AAE2E9BC-4D0B-4495-8825-DF8C405DB4A0}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{A8453835-4EE8-4FD4-9766-9C0DCB54CDB3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{A8453835-4EE8-4FD4-9766-9C0DCB54CDB3}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{A8453835-4EE8-4FD4-9766-9C0DCB54CDB3}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
@ -90,6 +88,10 @@ Global
|
||||
{561E0BFB-7817-41FE-BAF2-D78817679AC1}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{561E0BFB-7817-41FE-BAF2-D78817679AC1}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{561E0BFB-7817-41FE-BAF2-D78817679AC1}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{9689135B-44BA-4D55-8663-7C669BAFE066}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{9689135B-44BA-4D55-8663-7C669BAFE066}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{9689135B-44BA-4D55-8663-7C669BAFE066}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{9689135B-44BA-4D55-8663-7C669BAFE066}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{D1B321C9-3004-4645-A78D-A85C152062FA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{D1B321C9-3004-4645-A78D-A85C152062FA}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{D1B321C9-3004-4645-A78D-A85C152062FA}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
@ -98,34 +100,25 @@ Global
|
||||
{65E51735-73CE-4E9B-AA65-4BF5E4C8A705}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{65E51735-73CE-4E9B-AA65-4BF5E4C8A705}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{65E51735-73CE-4E9B-AA65-4BF5E4C8A705}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{AAE2E9BC-4D0B-4495-8825-DF8C405DB4A0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{AAE2E9BC-4D0B-4495-8825-DF8C405DB4A0}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{AAE2E9BC-4D0B-4495-8825-DF8C405DB4A0}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{AAE2E9BC-4D0B-4495-8825-DF8C405DB4A0}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{9689135B-44BA-4D55-8663-7C669BAFE066}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{9689135B-44BA-4D55-8663-7C669BAFE066}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{9689135B-44BA-4D55-8663-7C669BAFE066}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{9689135B-44BA-4D55-8663-7C669BAFE066}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(NestedProjects) = preSolution
|
||||
{63F7116F-320A-4CD8-9B84-2C675412F70F} = {3E34ADB9-1F52-4C96-9A42-DE782DE1AAA3}
|
||||
{082C1F69-7932-473F-A700-49584371BE8C} = {3E34ADB9-1F52-4C96-9A42-DE782DE1AAA3}
|
||||
{6FE502D4-C43D-49C9-9E57-D1EE566FD1C3} = {3E34ADB9-1F52-4C96-9A42-DE782DE1AAA3}
|
||||
{CDD123E6-2622-4368-BAEE-8B95F05F1AB2} = {3E34ADB9-1F52-4C96-9A42-DE782DE1AAA3}
|
||||
{7F155EFB-152F-4798-9984-99102B21D2F8} = {3E34ADB9-1F52-4C96-9A42-DE782DE1AAA3}
|
||||
{AAE2E9BC-4D0B-4495-8825-DF8C405DB4A0} = {3E34ADB9-1F52-4C96-9A42-DE782DE1AAA3}
|
||||
{4C48D9D5-1D7F-4616-A05D-256555C310FC} = {C95AF531-CF44-44AA-AC90-F4DF9F941674}
|
||||
{A8453835-4EE8-4FD4-9766-9C0DCB54CDB3} = {4C48D9D5-1D7F-4616-A05D-256555C310FC}
|
||||
{0C87A7D9-26EA-4821-AF3F-6D28B3006B24} = {C95AF531-CF44-44AA-AC90-F4DF9F941674}
|
||||
{5ECE2E7A-9AE8-49BF-902D-41A7756C3E78} = {C95AF531-CF44-44AA-AC90-F4DF9F941674}
|
||||
{DBF84F66-1436-4599-93AB-7C16A3A2C3A4} = {C95AF531-CF44-44AA-AC90-F4DF9F941674}
|
||||
{561E0BFB-7817-41FE-BAF2-D78817679AC1} = {C95AF531-CF44-44AA-AC90-F4DF9F941674}
|
||||
{9689135B-44BA-4D55-8663-7C669BAFE066} = {C95AF531-CF44-44AA-AC90-F4DF9F941674}
|
||||
{D1B321C9-3004-4645-A78D-A85C152062FA} = {35C901ED-C234-4A91-9561-AD89B3BB788D}
|
||||
{65E51735-73CE-4E9B-AA65-4BF5E4C8A705} = {35C901ED-C234-4A91-9561-AD89B3BB788D}
|
||||
{AAE2E9BC-4D0B-4495-8825-DF8C405DB4A0} = {3E34ADB9-1F52-4C96-9A42-DE782DE1AAA3}
|
||||
{9689135B-44BA-4D55-8663-7C669BAFE066} = {C95AF531-CF44-44AA-AC90-F4DF9F941674}
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {F08ED64E-2517-4B51-A4BE-D33D56CC7B39}
|
||||
|
@ -1,18 +1,13 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Xml;
|
||||
using System.Xml.Linq;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Options;
|
||||
|
||||
namespace SKIT.FlurlHttpClient.Wechat.Api.Sample_Net5.Controllers
|
||||
{
|
||||
using SKIT.FlurlHttpClient.Wechat.Security;
|
||||
using SKIT.FlurlHttpClient.Wechat.Api.Events;
|
||||
|
||||
[ApiController]
|
||||
|
@ -38,7 +38,7 @@ namespace SKIT.FlurlHttpClient.Wechat.Ads
|
||||
|
||||
if (request.FileHash == null)
|
||||
{
|
||||
request.FileHash = Security.MD5Utility.Hash(request.FileBytes ?? new byte[0]);
|
||||
request.FileHash = Utilities.MD5Utility.Hash(request.FileBytes ?? new byte[0]);
|
||||
}
|
||||
|
||||
string boundary = "--BOUNDARY--" + DateTimeOffset.Now.Ticks.ToString("x");
|
||||
|
@ -24,7 +24,7 @@ namespace SKIT.FlurlHttpClient.Wechat.Ads.Interceptors
|
||||
|
||||
string timestamp = DateTimeOffset.Now.ToLocalTime().ToUnixTimeSeconds().ToString();
|
||||
string nonce = Guid.NewGuid().ToString("N");
|
||||
string sign = Security.MD5Utility.Hash($"{_agencyId}{timestamp}{nonce}{_agencyApiKey}").ToLower();
|
||||
string sign = Utilities.MD5Utility.Hash($"{_agencyId}{timestamp}{nonce}{_agencyApiKey}").ToLower();
|
||||
string token = Convert.ToBase64String(Encoding.UTF8.GetBytes($"{_agencyId},{timestamp},{nonce},{sign}"));
|
||||
|
||||
flurlCall.Request.RemoveQueryParam("agency_token");
|
||||
|
@ -1,7 +1,7 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFrameworks>net461; netstandard2.0; net5.0</TargetFrameworks>
|
||||
<TargetFrameworks>net461; netstandard2.0; net5.0; net6.0</TargetFrameworks>
|
||||
<LangVersion>8.0</LangVersion>
|
||||
<Nullable>enable</Nullable>
|
||||
<NullableReferenceTypes>true</NullableReferenceTypes>
|
||||
@ -27,11 +27,7 @@
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.0.0" PrivateAssets="All" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\SKIT.FlurlHttpClient.Wechat\SKIT.FlurlHttpClient.Wechat.csproj" />
|
||||
<PackageReference Include="SKIT.FlurlHttpClient.Common" Version="2.0.0" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
@ -2,7 +2,7 @@
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
|
||||
namespace SKIT.FlurlHttpClient.Wechat.Security
|
||||
namespace SKIT.FlurlHttpClient.Wechat.Ads.Utilities
|
||||
{
|
||||
/// <summary>
|
||||
/// MD5 算法工具类。
|
@ -1,21 +1,18 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Flurl.Http;
|
||||
using Flurl.Http.Configuration;
|
||||
|
||||
namespace SKIT.FlurlHttpClient.Wechat.Ads
|
||||
{
|
||||
/// <summary>
|
||||
/// 一个微信广告平台 API HTTP 客户端。
|
||||
/// </summary>
|
||||
public class WechatAdsClient : CommonClientBase, IWechatClient
|
||||
public class WechatAdsClient : CommonClientBase, ICommonClient
|
||||
{
|
||||
/// <summary>
|
||||
/// 获取当前客户端使用的微信广告平台凭证。
|
||||
|
@ -3,7 +3,7 @@
|
||||
/// <summary>
|
||||
/// 微信广告平台 API 请求的基类。
|
||||
/// </summary>
|
||||
public abstract class WechatAdsRequest : IWechatRequest
|
||||
public abstract class WechatAdsRequest : ICommonRequest
|
||||
{
|
||||
/// <summary>
|
||||
/// 获取或设置请求超时时间(单位:毫秒)。如果不指定将使用构造 <see cref="WechatAdsClient"/> 时的 <see cref="WechatAdsClientOptions.Timeout"/> 参数,这在需要指定特定耗时请求(比如上传或下载文件)的超时时间时很有用。
|
||||
|
@ -6,7 +6,7 @@ namespace SKIT.FlurlHttpClient.Wechat.Ads
|
||||
/// <summary>
|
||||
/// 微信广告平台 API 响应的基类。
|
||||
/// </summary>
|
||||
public abstract class WechatAdsResponse : IWechatResponse
|
||||
public abstract class WechatAdsResponse : ICommonResponse
|
||||
{
|
||||
/// <summary>
|
||||
/// 获取原始的 HTTP 响应状态码。
|
||||
|
@ -270,7 +270,7 @@ namespace SKIT.FlurlHttpClient.Wechat.Api
|
||||
if (callbackSignature == null) throw new ArgumentNullException(nameof(callbackSignature));
|
||||
|
||||
ISet<string> set = new SortedSet<string>(StringComparer.Ordinal) { client.Credentials.PushToken!, callbackTimestamp, callbackNonce };
|
||||
string sign = Security.SHA1Utility.Hash(string.Concat(set));
|
||||
string sign = Utilities.SHA1Utility.Hash(string.Concat(set));
|
||||
return string.Equals(sign, callbackSignature, StringComparison.InvariantCultureIgnoreCase);
|
||||
}
|
||||
|
||||
|
@ -25,7 +25,7 @@ namespace SKIT.FlurlHttpClient.Wechat.Api
|
||||
if (request.DeliverySignature == null)
|
||||
{
|
||||
string plainText = $"{request.ShopId}{request.ShopOrderId}{client.Credentials.ImmeDeliveryAppSecret}";
|
||||
request.DeliverySignature = Security.SHA1Utility.Hash(plainText).ToLower();
|
||||
request.DeliverySignature = Utilities.SHA1Utility.Hash(plainText).ToLower();
|
||||
}
|
||||
|
||||
return request;
|
||||
|
@ -47,7 +47,7 @@ namespace SKIT.FlurlHttpClient.Wechat.Api
|
||||
+ $"&org_loc={reqLoc}"
|
||||
+ $"&method={method.ToUpper()}"
|
||||
+ $"&secret={client.Credentials.MidasAppKey}";
|
||||
request.Signature = Security.HMACSHA256Utility.Hash(client.Credentials.MidasAppKey ?? string.Empty, plainText).ToLower();
|
||||
request.Signature = Utilities.HMACSHA256Utility.Hash(client.Credentials.MidasAppKey ?? string.Empty, plainText).ToLower();
|
||||
}
|
||||
|
||||
return request;
|
||||
|
@ -25,7 +25,7 @@ namespace SKIT.FlurlHttpClient.Wechat.Api
|
||||
|
||||
string timestamp = DateTimeOffset.Now.ToLocalTime().ToUnixTimeSeconds().ToString();
|
||||
string nonce = Guid.NewGuid().ToString("N");
|
||||
string sign = Security.SHA1Utility.Hash($"jsapi_ticket={jsapiTicket}&noncestr={nonce}×tamp={timestamp}&url={url.Split('#')[0]}").ToLower();
|
||||
string sign = Utilities.SHA1Utility.Hash($"jsapi_ticket={jsapiTicket}&noncestr={nonce}×tamp={timestamp}&url={url.Split('#')[0]}").ToLower();
|
||||
|
||||
return new ReadOnlyDictionary<string, string>(new Dictionary<string, string>()
|
||||
{
|
||||
@ -58,7 +58,7 @@ namespace SKIT.FlurlHttpClient.Wechat.Api
|
||||
sortedParams.Add(client.Credentials.AppId);
|
||||
sortedParams.Add(nonce);
|
||||
sortedParams.Add(wxcardTicket);
|
||||
string cardSign = Security.SHA1Utility.Hash(string.Join(string.Empty, sortedParams)).ToLower();
|
||||
string cardSign = Utilities.SHA1Utility.Hash(string.Join(string.Empty, sortedParams)).ToLower();
|
||||
|
||||
return new ReadOnlyDictionary<string, string>(new Dictionary<string, string>()
|
||||
{
|
||||
|
@ -1,7 +1,7 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFrameworks>net461; netstandard2.0; net5.0</TargetFrameworks>
|
||||
<TargetFrameworks>net461; netstandard2.0; net5.0; net6.0</TargetFrameworks>
|
||||
<LangVersion>8.0</LangVersion>
|
||||
<Nullable>enable</Nullable>
|
||||
<NullableReferenceTypes>true</NullableReferenceTypes>
|
||||
@ -26,12 +26,8 @@
|
||||
<Reference Include="System.Web" Condition="'$(TargetFramework)' == 'net461'" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.0.0" PrivateAssets="All" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\SKIT.FlurlHttpClient.Wechat\SKIT.FlurlHttpClient.Wechat.csproj" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="SKIT.FlurlHttpClient.Common" Version="2.0.0" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
@ -2,7 +2,7 @@
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
|
||||
namespace SKIT.FlurlHttpClient.Wechat.Security
|
||||
namespace SKIT.FlurlHttpClient.Wechat.Api.Utilities
|
||||
{
|
||||
/// <summary>
|
||||
/// HMAC-SHA-256 算法工具类。
|
@ -2,7 +2,7 @@
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
|
||||
namespace SKIT.FlurlHttpClient.Wechat.Security
|
||||
namespace SKIT.FlurlHttpClient.Wechat.Api.Utilities
|
||||
{
|
||||
/// <summary>
|
||||
/// SHA-1 算法工具类。
|
@ -81,7 +81,7 @@ namespace SKIT.FlurlHttpClient.Wechat.Api.Utilities
|
||||
if (ivBytes == null) throw new ArgumentNullException(nameof(ivBytes));
|
||||
if (ciperBytes == null) throw new ArgumentNullException(nameof(ciperBytes));
|
||||
|
||||
using RijndaelManaged aes = new RijndaelManaged();
|
||||
using var aes = Aes.Create();
|
||||
aes.KeySize = 256;
|
||||
aes.BlockSize = 128;
|
||||
aes.Mode = CipherMode.CBC;
|
||||
@ -109,7 +109,7 @@ namespace SKIT.FlurlHttpClient.Wechat.Api.Utilities
|
||||
if (ivBytes == null) throw new ArgumentNullException(nameof(ivBytes));
|
||||
if (plainBytes == null) throw new ArgumentNullException(nameof(plainBytes));
|
||||
|
||||
using var aes = new RijndaelManaged();
|
||||
using var aes = Aes.Create();
|
||||
aes.KeySize = AES_KEY_SIZE;
|
||||
aes.BlockSize = AES_BLOCK_SIZE;
|
||||
//aes.Padding = PaddingMode.PKCS7;
|
||||
@ -238,7 +238,7 @@ namespace SKIT.FlurlHttpClient.Wechat.Api.Utilities
|
||||
set.Add(sMsgEncrypt);
|
||||
|
||||
string rawText = string.Join(string.Empty, set.ToArray());
|
||||
string signText = Security.SHA1Utility.Hash(rawText);
|
||||
string signText = Utilities.SHA1Utility.Hash(rawText);
|
||||
return signText.ToLower();
|
||||
}
|
||||
|
||||
@ -270,7 +270,7 @@ namespace SKIT.FlurlHttpClient.Wechat.Api.Utilities
|
||||
try
|
||||
{
|
||||
XmlDocument xmlDoc = new XmlDocument();
|
||||
xmlDoc.XmlResolver = null;
|
||||
xmlDoc.XmlResolver = null!;
|
||||
xmlDoc.LoadXml(xml);
|
||||
|
||||
XmlNode? xmlRoot = xmlDoc.FirstChild;
|
||||
|
@ -1,24 +1,21 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Flurl.Http;
|
||||
using Flurl.Http.Configuration;
|
||||
|
||||
namespace SKIT.FlurlHttpClient.Wechat.Api
|
||||
{
|
||||
/// <summary>
|
||||
/// 一个微信 API HTTP 客户端。
|
||||
/// </summary>
|
||||
public class WechatApiClient : CommonClientBase, IWechatClient
|
||||
public class WechatApiClient : CommonClientBase, ICommonClient
|
||||
{
|
||||
/// <summary>
|
||||
/// 获取当前客户端使用的微信公众平台凭证。
|
||||
/// 获取当前客户端使用的微信公众平台/开放平台凭证。
|
||||
/// </summary>
|
||||
public Settings.Credentials Credentials { get; }
|
||||
|
||||
|
@ -5,7 +5,7 @@ namespace SKIT.FlurlHttpClient.Wechat.Api
|
||||
/// <summary>
|
||||
/// 表示微信 API 请求的基类。
|
||||
/// </summary>
|
||||
public abstract class WechatApiRequest : IWechatRequest
|
||||
public abstract class WechatApiRequest : ICommonRequest
|
||||
{
|
||||
/// <summary>
|
||||
/// 获取或设置请求超时时间(单位:毫秒)。如果不指定将使用构造 <see cref="WechatApiClient"/> 时的 <see cref="WechatApiClientOptions.Timeout"/> 参数,这在需要指定特定耗时请求(比如上传或下载文件)的超时时间时很有用。
|
||||
|
@ -6,7 +6,7 @@ namespace SKIT.FlurlHttpClient.Wechat.Api
|
||||
/// <summary>
|
||||
/// 表示微信 API 响应的基类。
|
||||
/// </summary>
|
||||
public abstract class WechatApiResponse : IWechatResponse
|
||||
public abstract class WechatApiResponse : ICommonResponse
|
||||
{
|
||||
/// <summary>
|
||||
/// 获取原始的 HTTP 响应状态码。
|
||||
|
@ -1,7 +1,7 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFrameworks>net461; netstandard2.0; net5.0</TargetFrameworks>
|
||||
<TargetFrameworks>net461; netstandard2.0; net5.0; net6.0</TargetFrameworks>
|
||||
<LangVersion>8.0</LangVersion>
|
||||
<Nullable>enable</Nullable>
|
||||
<NullableReferenceTypes>true</NullableReferenceTypes>
|
||||
@ -28,11 +28,7 @@
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="JWT" Version="8.4.2" />
|
||||
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.0.0" PrivateAssets="All" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\SKIT.FlurlHttpClient.Wechat\SKIT.FlurlHttpClient.Wechat.csproj" />
|
||||
</ItemGroup>
|
||||
<PackageReference Include="SKIT.FlurlHttpClient.Common" Version="2.0.0" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
@ -2,43 +2,38 @@
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
|
||||
namespace SKIT.FlurlHttpClient.Wechat.Security
|
||||
namespace SKIT.FlurlHttpClient.Wechat.OpenAI.Utilities
|
||||
{
|
||||
/// <summary>
|
||||
/// HMAC-SHA-1 算法工具类。
|
||||
/// SHA-1 算法工具类。
|
||||
/// </summary>
|
||||
public static class HMACSHA1Utility
|
||||
public static class SHA1Utility
|
||||
{
|
||||
/// <summary>
|
||||
/// 获取信息摘要。
|
||||
/// </summary>
|
||||
/// <param name="secretBytes">密钥字节数组。</param>
|
||||
/// <param name="bytes">信息字节数组。</param>
|
||||
/// <returns>信息摘要。</returns>
|
||||
public static string Hash(byte[] secretBytes, byte[] bytes)
|
||||
public static string Hash(byte[] bytes)
|
||||
{
|
||||
if (secretBytes == null) throw new ArgumentNullException(nameof(secretBytes));
|
||||
if (bytes == null) throw new ArgumentNullException(nameof(bytes));
|
||||
|
||||
using HMAC hmac = new HMACSHA1(secretBytes);
|
||||
byte[] hashBytes = hmac.ComputeHash(bytes);
|
||||
using SHA1 sha = SHA1.Create();
|
||||
byte[] hashBytes = sha.ComputeHash(bytes);
|
||||
return BitConverter.ToString(hashBytes).Replace("-", "");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取信息摘要。
|
||||
/// </summary>
|
||||
/// <param name="secret">密钥。</param>
|
||||
/// <param name="message">文本信息。</param>
|
||||
/// <returns>信息摘要。</returns>
|
||||
public static string Hash(string secret, string message)
|
||||
public static string Hash(string message)
|
||||
{
|
||||
if (secret == null) throw new ArgumentNullException(nameof(secret));
|
||||
if (message == null) throw new ArgumentNullException(nameof(message));
|
||||
|
||||
byte[] secretBytes = Encoding.UTF8.GetBytes(secret);
|
||||
byte[] bytes = Encoding.UTF8.GetBytes(message);
|
||||
return Hash(secretBytes, bytes);
|
||||
return Hash(bytes);
|
||||
}
|
||||
}
|
||||
}
|
@ -80,7 +80,7 @@ namespace SKIT.FlurlHttpClient.Wechat.OpenAI.Utilities
|
||||
if (ivBytes == null) throw new ArgumentNullException(nameof(ivBytes));
|
||||
if (ciperBytes == null) throw new ArgumentNullException(nameof(ciperBytes));
|
||||
|
||||
using RijndaelManaged aes = new RijndaelManaged();
|
||||
using var aes = Aes.Create();
|
||||
aes.KeySize = 256;
|
||||
aes.BlockSize = 128;
|
||||
aes.Mode = CipherMode.CBC;
|
||||
@ -108,7 +108,7 @@ namespace SKIT.FlurlHttpClient.Wechat.OpenAI.Utilities
|
||||
if (ivBytes == null) throw new ArgumentNullException(nameof(ivBytes));
|
||||
if (plainBytes == null) throw new ArgumentNullException(nameof(plainBytes));
|
||||
|
||||
using var aes = new RijndaelManaged();
|
||||
using var aes = Aes.Create();
|
||||
aes.KeySize = AES_KEY_SIZE;
|
||||
aes.BlockSize = AES_BLOCK_SIZE;
|
||||
//aes.Padding = PaddingMode.PKCS7;
|
||||
@ -237,7 +237,7 @@ namespace SKIT.FlurlHttpClient.Wechat.OpenAI.Utilities
|
||||
set.Add(sMsgEncrypt);
|
||||
|
||||
string rawText = string.Join(string.Empty, set.ToArray());
|
||||
string signText = Security.SHA1Utility.Hash(rawText);
|
||||
string signText = Utilities.SHA1Utility.Hash(rawText);
|
||||
return signText.ToLower();
|
||||
}
|
||||
|
||||
@ -269,7 +269,7 @@ namespace SKIT.FlurlHttpClient.Wechat.OpenAI.Utilities
|
||||
try
|
||||
{
|
||||
XmlDocument xmlDoc = new XmlDocument();
|
||||
xmlDoc.XmlResolver = null;
|
||||
xmlDoc.XmlResolver = null!;
|
||||
xmlDoc.LoadXml(xml);
|
||||
|
||||
XmlNode? xmlRoot = xmlDoc.FirstChild;
|
||||
|
@ -12,7 +12,7 @@ namespace SKIT.FlurlHttpClient.Wechat.OpenAI
|
||||
/// <summary>
|
||||
/// 一个微信智能对话平台接入 API HTTP 客户端。
|
||||
/// </summary>
|
||||
public class WechatOpenAIPlatformClient : CommonClientBase, IWechatClient
|
||||
public class WechatOpenAIPlatformClient : CommonClientBase, ICommonClient
|
||||
{
|
||||
/// <summary>
|
||||
/// 获取当前客户端使用的微信智能对话平台凭证。
|
||||
|
@ -5,7 +5,7 @@ namespace SKIT.FlurlHttpClient.Wechat.OpenAI
|
||||
/// <summary>
|
||||
/// 表示微信智能对话平台接入 API 请求的基类。
|
||||
/// </summary>
|
||||
public abstract class WechatOpenAIPlatformRequest : IWechatRequest
|
||||
public abstract class WechatOpenAIPlatformRequest : ICommonRequest
|
||||
{
|
||||
public static class Serialization
|
||||
{
|
||||
|
@ -6,7 +6,7 @@ namespace SKIT.FlurlHttpClient.Wechat.OpenAI
|
||||
/// <summary>
|
||||
/// 表示微信智能对话平台接入 API 响应的基类。
|
||||
/// </summary>
|
||||
public abstract class WechatOpenAIPlatformResponse : IWechatResponse
|
||||
public abstract class WechatOpenAIPlatformResponse : ICommonResponse
|
||||
{
|
||||
/// <summary>
|
||||
/// 获取原始的 HTTP 响应状态码。
|
||||
|
@ -12,7 +12,7 @@ namespace SKIT.FlurlHttpClient.Wechat.OpenAI
|
||||
/// <summary>
|
||||
/// 一个微信智能对话第三方接入 API HTTP 客户端。
|
||||
/// </summary>
|
||||
public class WechatOpenAIThirdPartyClient : CommonClientBase, IWechatClient
|
||||
public class WechatOpenAIThirdPartyClient : CommonClientBase, ICommonClient
|
||||
{
|
||||
/// <summary>
|
||||
/// 获取当前客户端使用的微信智能对话平台凭证。
|
||||
|
@ -5,7 +5,7 @@ namespace SKIT.FlurlHttpClient.Wechat.OpenAI
|
||||
/// <summary>
|
||||
/// 表示微信智能对话第三方接入 API 请求的基类。
|
||||
/// </summary>
|
||||
public abstract class WechatOpenAIThirdPartyRequest : IWechatRequest
|
||||
public abstract class WechatOpenAIThirdPartyRequest : ICommonRequest
|
||||
{
|
||||
/// <summary>
|
||||
/// 获取或设置请求超时时间(单位:毫秒)。如果不指定将使用构造 <see cref="WechatOpenAIPlatformClient"/> 时的 <see cref="WechatOpenAIPlatformClientOptions.Timeout"/> 参数,这在需要指定特定耗时请求(比如上传或下载文件)的超时时间时很有用。
|
||||
|
@ -6,7 +6,7 @@ namespace SKIT.FlurlHttpClient.Wechat.OpenAI
|
||||
/// <summary>
|
||||
/// 表示微信智能对话第三方接入 API 响应的基类。
|
||||
/// </summary>
|
||||
public abstract class WechatOpenAIThirdPartyResponse : IWechatResponse
|
||||
public abstract class WechatOpenAIThirdPartyResponse : ICommonResponse
|
||||
{
|
||||
/// <summary>
|
||||
/// 获取原始的 HTTP 响应状态码。
|
||||
|
@ -34,7 +34,7 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3
|
||||
request.FileName = Guid.NewGuid().ToString("N").ToLower() + ".txt";
|
||||
|
||||
if (request.FileHash == null)
|
||||
request.FileHash = Security.SHA256Utility.Hash(request.FileBytes).ToLower();
|
||||
request.FileHash = Utilities.SHA256Utility.Hash(request.FileBytes).ToLower();
|
||||
|
||||
if (request.FileContentType == null)
|
||||
request.FileContentType = Utilities.FileNameToContentTypeMapper.GetContentTypeForImage(request.FileName!) ?? "text/plain";
|
||||
|
@ -34,7 +34,7 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3
|
||||
request.FileName = Guid.NewGuid().ToString("N").ToLower() + ".png";
|
||||
|
||||
if (request.FileHash == null)
|
||||
request.FileHash = Security.SHA256Utility.Hash(request.FileBytes).ToLower();
|
||||
request.FileHash = Utilities.SHA256Utility.Hash(request.FileBytes).ToLower();
|
||||
|
||||
if (request.FileContentType == null)
|
||||
request.FileContentType = Utilities.FileNameToContentTypeMapper.GetContentTypeForImage(request.FileName!) ?? "image/png";
|
||||
|
@ -34,7 +34,7 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3
|
||||
request.FileName = Guid.NewGuid().ToString("N").ToLower() + ".png";
|
||||
|
||||
if (request.FileHash == null)
|
||||
request.FileHash = Security.SHA256Utility.Hash(request.FileBytes).ToLower();
|
||||
request.FileHash = Utilities.SHA256Utility.Hash(request.FileBytes).ToLower();
|
||||
|
||||
if (request.FileContentType == null)
|
||||
request.FileContentType = Utilities.FileNameToContentTypeMapper.GetContentTypeForImage(request.FileName!) ?? "image/png";
|
||||
@ -73,7 +73,7 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3
|
||||
request.FileName = Guid.NewGuid().ToString("N").ToLower() + ".mp4";
|
||||
|
||||
if (request.FileHash == null)
|
||||
request.FileHash = Security.SHA256Utility.Hash(request.FileBytes).ToLower();
|
||||
request.FileHash = Utilities.SHA256Utility.Hash(request.FileBytes).ToLower();
|
||||
|
||||
if (request.FileContentType == null)
|
||||
request.FileContentType = Utilities.FileNameToContentTypeMapper.GetContentTypeForVideo(request.FileName!) ?? "video/mp4";
|
||||
|
@ -237,7 +237,7 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3
|
||||
request.FileName = Guid.NewGuid().ToString("N").ToLower() + ".png";
|
||||
|
||||
if (request.FileHash == null)
|
||||
request.FileHash = Security.SHA256Utility.Hash(request.FileBytes).ToLower();
|
||||
request.FileHash = Utilities.SHA256Utility.Hash(request.FileBytes).ToLower();
|
||||
|
||||
if (request.FileContentType == null)
|
||||
request.FileContentType = Utilities.FileNameToContentTypeMapper.GetContentTypeForImage(request.FileName!) ?? "image/png";
|
||||
|
@ -1,7 +1,7 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFrameworks>net461; netstandard2.0; net5.0</TargetFrameworks>
|
||||
<TargetFrameworks>net461; netstandard2.0; net5.0; net6.0</TargetFrameworks>
|
||||
<LangVersion>8.0</LangVersion>
|
||||
<Nullable>enable</Nullable>
|
||||
<NullableReferenceTypes>true</NullableReferenceTypes>
|
||||
@ -27,12 +27,8 @@
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.0.0" PrivateAssets="All" />
|
||||
<PackageReference Include="Portable.BouncyCastle" Version="1.8.10" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\SKIT.FlurlHttpClient.Wechat\SKIT.FlurlHttpClient.Wechat.csproj" />
|
||||
<PackageReference Include="SKIT.FlurlHttpClient.Common" Version="2.0.0" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
@ -2,7 +2,7 @@
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
|
||||
namespace SKIT.FlurlHttpClient.Wechat.Security
|
||||
namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Utilities
|
||||
{
|
||||
/// <summary>
|
||||
/// SHA-256 算法工具类。
|
@ -1,23 +1,19 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Net.Http.Headers;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Flurl;
|
||||
using Flurl.Http;
|
||||
using Flurl.Http.Configuration;
|
||||
|
||||
namespace SKIT.FlurlHttpClient.Wechat.TenpayV3
|
||||
{
|
||||
/// <summary>
|
||||
/// 一个微信支付 API HTTP 客户端。
|
||||
/// </summary>
|
||||
public class WechatTenpayClient : CommonClientBase, IWechatClient
|
||||
public class WechatTenpayClient : CommonClientBase, ICommonClient
|
||||
{
|
||||
/// <summary>
|
||||
/// 获取当前客户端使用的微信商户平台凭证。
|
||||
|
@ -5,7 +5,7 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3
|
||||
/// <summary>
|
||||
/// 表示微信支付 API 请求的基类。
|
||||
/// </summary>
|
||||
public abstract class WechatTenpayRequest : IWechatRequest
|
||||
public abstract class WechatTenpayRequest : ICommonRequest
|
||||
{
|
||||
/// <summary>
|
||||
/// 获取或设置请求超时时间(单位:毫秒)。如果不指定将使用构造 <see cref="WechatTenpayClient"/> 时的 <see cref="WechatTenpayClientOptions.Timeout"/> 参数,这在需要指定特定耗时请求(比如上传或下载文件)的超时时间时很有用。
|
||||
|
@ -6,7 +6,7 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3
|
||||
/// <summary>
|
||||
/// 表示微信支付 API 响应的基类。
|
||||
/// </summary>
|
||||
public abstract class WechatTenpayResponse : IWechatResponse
|
||||
public abstract class WechatTenpayResponse : ICommonResponse
|
||||
{
|
||||
/// <summary>
|
||||
/// 获取原始的 HTTP 响应状态码。
|
||||
|
@ -35,7 +35,7 @@ namespace SKIT.FlurlHttpClient.Wechat.Work
|
||||
|
||||
string timestamp = DateTimeOffset.Now.ToLocalTime().ToUnixTimeSeconds().ToString();
|
||||
string nonce = Guid.NewGuid().ToString("N");
|
||||
string sign = Security.SHA1Utility.Hash($"jsapi_ticket={jsapiTicket}&noncestr={nonce}×tamp={timestamp}&url={url.Split('#')[0]}").ToLower();
|
||||
string sign = Utilities.SHA1Utility.Hash($"jsapi_ticket={jsapiTicket}&noncestr={nonce}×tamp={timestamp}&url={url.Split('#')[0]}").ToLower();
|
||||
|
||||
return new ReadOnlyDictionary<string, string>(new Dictionary<string, string>()
|
||||
{
|
||||
@ -64,7 +64,7 @@ namespace SKIT.FlurlHttpClient.Wechat.Work
|
||||
|
||||
string timestamp = DateTimeOffset.Now.ToLocalTime().ToUnixTimeSeconds().ToString();
|
||||
string nonce = Guid.NewGuid().ToString("N");
|
||||
string sign = Security.SHA1Utility.Hash($"jsapi_ticket={jsapiTicket}&noncestr={nonce}×tamp={timestamp}&url={url.Split('#')[0]}").ToLower();
|
||||
string sign = Utilities.SHA1Utility.Hash($"jsapi_ticket={jsapiTicket}&noncestr={nonce}×tamp={timestamp}&url={url.Split('#')[0]}").ToLower();
|
||||
|
||||
return new ReadOnlyDictionary<string, string>(new Dictionary<string, string>()
|
||||
{
|
||||
|
@ -1,7 +1,7 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFrameworks>net461; netstandard2.0; net5.0</TargetFrameworks>
|
||||
<TargetFrameworks>net461; netstandard2.0; net5.0; net6.0</TargetFrameworks>
|
||||
<LangVersion>8.0</LangVersion>
|
||||
<Nullable>enable</Nullable>
|
||||
<NullableReferenceTypes>true</NullableReferenceTypes>
|
||||
@ -27,11 +27,7 @@
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.0.0" PrivateAssets="All" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\SKIT.FlurlHttpClient.Wechat\SKIT.FlurlHttpClient.Wechat.csproj" />
|
||||
<PackageReference Include="SKIT.FlurlHttpClient.Common" Version="2.0.0" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
@ -0,0 +1,39 @@
|
||||
using System;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
|
||||
namespace SKIT.FlurlHttpClient.Wechat.Work.Utilities
|
||||
{
|
||||
/// <summary>
|
||||
/// SHA-1 算法工具类。
|
||||
/// </summary>
|
||||
public static class SHA1Utility
|
||||
{
|
||||
/// <summary>
|
||||
/// 获取信息摘要。
|
||||
/// </summary>
|
||||
/// <param name="bytes">信息字节数组。</param>
|
||||
/// <returns>信息摘要。</returns>
|
||||
public static string Hash(byte[] bytes)
|
||||
{
|
||||
if (bytes == null) throw new ArgumentNullException(nameof(bytes));
|
||||
|
||||
using SHA1 sha = SHA1.Create();
|
||||
byte[] hashBytes = sha.ComputeHash(bytes);
|
||||
return BitConverter.ToString(hashBytes).Replace("-", "");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取信息摘要。
|
||||
/// </summary>
|
||||
/// <param name="message">文本信息。</param>
|
||||
/// <returns>信息摘要。</returns>
|
||||
public static string Hash(string message)
|
||||
{
|
||||
if (message == null) throw new ArgumentNullException(nameof(message));
|
||||
|
||||
byte[] bytes = Encoding.UTF8.GetBytes(message);
|
||||
return Hash(bytes);
|
||||
}
|
||||
}
|
||||
}
|
@ -81,7 +81,7 @@ namespace SKIT.FlurlHttpClient.Wechat.Work.Utilities
|
||||
if (ivBytes == null) throw new ArgumentNullException(nameof(ivBytes));
|
||||
if (cipherBytes == null) throw new ArgumentNullException(nameof(cipherBytes));
|
||||
|
||||
using RijndaelManaged aes = new RijndaelManaged();
|
||||
using var aes = Aes.Create();
|
||||
aes.KeySize = 256;
|
||||
aes.BlockSize = 128;
|
||||
aes.Mode = CipherMode.CBC;
|
||||
@ -109,7 +109,7 @@ namespace SKIT.FlurlHttpClient.Wechat.Work.Utilities
|
||||
if (ivBytes == null) throw new ArgumentNullException(nameof(ivBytes));
|
||||
if (plainBytes == null) throw new ArgumentNullException(nameof(plainBytes));
|
||||
|
||||
using var aes = new RijndaelManaged();
|
||||
using var aes = Aes.Create();
|
||||
aes.KeySize = AES_KEY_SIZE;
|
||||
aes.BlockSize = AES_BLOCK_SIZE;
|
||||
//aes.Padding = PaddingMode.PKCS7;
|
||||
@ -238,7 +238,7 @@ namespace SKIT.FlurlHttpClient.Wechat.Work.Utilities
|
||||
set.Add(sMsgEncrypt);
|
||||
|
||||
string rawText = string.Join(string.Empty, set.ToArray());
|
||||
string signText = Security.SHA1Utility.Hash(rawText);
|
||||
string signText = Utilities.SHA1Utility.Hash(rawText);
|
||||
return signText.ToLower();
|
||||
}
|
||||
|
||||
@ -273,7 +273,7 @@ namespace SKIT.FlurlHttpClient.Wechat.Work.Utilities
|
||||
try
|
||||
{
|
||||
XmlDocument xmlDoc = new XmlDocument();
|
||||
xmlDoc.XmlResolver = null;
|
||||
xmlDoc.XmlResolver = null!;
|
||||
xmlDoc.LoadXml(xml);
|
||||
|
||||
XmlNode? xmlRoot = xmlDoc.FirstChild;
|
||||
|
@ -1,21 +1,18 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Flurl.Http;
|
||||
using Flurl.Http.Configuration;
|
||||
|
||||
namespace SKIT.FlurlHttpClient.Wechat.Work
|
||||
{
|
||||
/// <summary>
|
||||
/// 一个企业微信 API HTTP 客户端。
|
||||
/// </summary>
|
||||
public class WechatWorkClient : CommonClientBase, IWechatClient
|
||||
public class WechatWorkClient : CommonClientBase, ICommonClient
|
||||
{
|
||||
/// <summary>
|
||||
/// 获取当前客户端使用的企业微信凭证。
|
||||
|
@ -5,7 +5,7 @@ namespace SKIT.FlurlHttpClient.Wechat.Work
|
||||
/// <summary>
|
||||
/// 表示企业微信 API 请求的基类。
|
||||
/// </summary>
|
||||
public abstract class WechatWorkRequest : IWechatRequest
|
||||
public abstract class WechatWorkRequest : ICommonRequest
|
||||
{
|
||||
/// <summary>
|
||||
/// 获取或设置请求超时时间(单位:毫秒)。如果不指定将使用构造 <see cref="WechatWorkClient"/> 时的 <see cref="WechatWorkClientOptions.Timeout"/> 参数,这在需要指定特定耗时请求(比如上传或下载文件)的超时时间时很有用。
|
||||
|
@ -6,7 +6,7 @@ namespace SKIT.FlurlHttpClient.Wechat.Work
|
||||
/// <summary>
|
||||
/// 表示企业微信 API 响应的基类。
|
||||
/// </summary>
|
||||
public abstract class WechatWorkResponse : IWechatResponse
|
||||
public abstract class WechatWorkResponse : ICommonResponse
|
||||
{
|
||||
/// <summary>
|
||||
/// 获取原始的 HTTP 响应状态码。
|
||||
|
@ -1,14 +0,0 @@
|
||||
using System;
|
||||
using System.Net.Http;
|
||||
using Flurl.Http;
|
||||
using Flurl.Http.Configuration;
|
||||
|
||||
namespace SKIT.FlurlHttpClient.Wechat
|
||||
{
|
||||
/// <summary>
|
||||
/// SKIT.FlurlHttpClient.Wechat 客户端接口。
|
||||
/// </summary>
|
||||
public interface IWechatClient : ICommonClient
|
||||
{
|
||||
}
|
||||
}
|
@ -1,9 +0,0 @@
|
||||
namespace SKIT.FlurlHttpClient.Wechat
|
||||
{
|
||||
/// <summary>
|
||||
/// SKIT.FlurlHttpClient.Wechat 请求接口。
|
||||
/// </summary>
|
||||
public interface IWechatRequest : ICommonRequest
|
||||
{
|
||||
}
|
||||
}
|
@ -1,9 +0,0 @@
|
||||
namespace SKIT.FlurlHttpClient.Wechat
|
||||
{
|
||||
/// <summary>
|
||||
/// SKIT.FlurlHttpClient.Wechat 响应接口。
|
||||
/// </summary>
|
||||
public interface IWechatResponse : ICommonResponse
|
||||
{
|
||||
}
|
||||
}
|
@ -1,31 +0,0 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFrameworks>net461; netstandard2.0; net5.0</TargetFrameworks>
|
||||
<LangVersion>8.0</LangVersion>
|
||||
<Nullable>enable</Nullable>
|
||||
<NullableReferenceTypes>true</NullableReferenceTypes>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
<PackageId>SKIT.FlurlHttpClient.Wechat</PackageId>
|
||||
<PackageLicenseExpression>MIT</PackageLicenseExpression>
|
||||
<PackageProjectUrl>https://github.com/fudiwei/DotNetCore.SKIT.FlurlHttpClient.Wechat</PackageProjectUrl>
|
||||
<PackageTags>Flurl.Http Wechat Weixin MicroMessage 微信</PackageTags>
|
||||
<Version>1.1.0</Version>
|
||||
<Description>SKIT.FlurlClient.Wechat(含 SKIT.FlurlHttpClient.Wechat.Api、SKIT.FlurlHttpClient.Wechat.TenpayV3、SKIT.FlurlHttpClient.Wechat.Work、SKIT.FlurlHttpClient.Wechat.Ads 等模块)的核心库,具体用法请参阅开发文档。</Description>
|
||||
<Authors>Fu Diwei</Authors>
|
||||
<RepositoryType>git</RepositoryType>
|
||||
<RepositoryUrl>https://github.com/fudiwei/DotNetCore.SKIT.FlurlHttpClient.Wechat.git</RepositoryUrl>
|
||||
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
||||
<IncludeSymbols>true</IncludeSymbols>
|
||||
<SymbolPackageFormat>snupkg</SymbolPackageFormat>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.0.0" PrivateAssets="All" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
|
||||
<PackageReference Include="SKIT.FlurlHttpClient.Common" Version="1.0.0" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
@ -1,7 +1,7 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netcoreapp3.1</TargetFramework>
|
||||
<TargetFrameworks>netcoreapp3.1; net6.0</TargetFrameworks>
|
||||
<LangVersion>8.0</LangVersion>
|
||||
</PropertyGroup>
|
||||
|
||||
|
@ -15,7 +15,7 @@ namespace SKIT.FlurlHttpClient.Wechat.Ads.UnitTests
|
||||
{
|
||||
string rawData = "spidbff89d5138160943040012345678901234567890uFolxxiZbrZ/PRbyen5uK5D1kgIB2yHyDsfDGxxgeG";
|
||||
|
||||
string actualHash = Security.MD5Utility.Hash(rawData);
|
||||
string actualHash = Utilities.MD5Utility.Hash(rawData);
|
||||
string expectedHash = "32c03e8fcdb08e653e42805e302f70ed";
|
||||
|
||||
Assert.Equal(expectedHash, actualHash, ignoreCase: true);
|
||||
|
@ -1,7 +1,7 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netcoreapp3.1</TargetFramework>
|
||||
<TargetFrameworks>netcoreapp3.1; net6.0</TargetFrameworks>
|
||||
<LangVersion>8.0</LangVersion>
|
||||
</PropertyGroup>
|
||||
|
||||
|
@ -10,7 +10,7 @@ namespace SKIT.FlurlHttpClient.Wechat.Api.UnitTests
|
||||
{
|
||||
string rawData = "jsapi_ticket=HoagFKDcsGMVCIY2vOjf9nGrZ3eaM0qXs5ROFN_3k_HrGc0VocemA6wMXkvrL-Ei4IitXxwKF62CJWR8mWXZ3Q&noncestr=e7b435f73835402da44f16640ddc8696×tamp=1621348162&url=https://mp.weixin.qq.com/debug/cgi-bin/sandbox?t=jsapisign";
|
||||
|
||||
string actualHash = Security.SHA1Utility.Hash(rawData);
|
||||
string actualHash = Utilities.SHA1Utility.Hash(rawData);
|
||||
string expectedHash = "b214ea1f8ae019c207f8c6ffb843c8474cbab28c";
|
||||
|
||||
Assert.Equal(expectedHash, actualHash, ignoreCase: true);
|
||||
@ -22,7 +22,7 @@ namespace SKIT.FlurlHttpClient.Wechat.Api.UnitTests
|
||||
string secret = "zNLgAGgqsEWJOg1nFVaO5r7fAlIQxr1u";
|
||||
string rawData = "appid=wx1234567&offer_id=12345678&openid=odkx20ENSNa2w5y3g_qOkOvBNM1g&pf=android&ts=1507530737&zone_id=1&org_loc=/cgi-bin/midas/getbalance&method=POST&secret=zNLgAGgqsEWJOg1nFVaO5r7fAlIQxr1u";
|
||||
|
||||
string actualHash = Security.HMACSHA256Utility.Hash(secret, rawData);
|
||||
string actualHash = Utilities.HMACSHA256Utility.Hash(secret, rawData);
|
||||
string expectedHash = "1ad64e8dcb2ec1dc486b7fdf01f4a15159fc623dc3422470e51cf6870734726b";
|
||||
|
||||
Assert.Equal(expectedHash, actualHash, ignoreCase: true);
|
||||
|
@ -1,7 +1,7 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netcoreapp3.1</TargetFramework>
|
||||
<TargetFrameworks>netcoreapp3.1; net6.0</TargetFrameworks>
|
||||
<LangVersion>8.0</LangVersion>
|
||||
</PropertyGroup>
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netcoreapp3.1</TargetFramework>
|
||||
<TargetFrameworks>netcoreapp3.1; net6.0</TargetFrameworks>
|
||||
<LangVersion>8.0</LangVersion>
|
||||
</PropertyGroup>
|
||||
|
||||
|
@ -90,7 +90,7 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests
|
||||
{
|
||||
string rawData = "This is raw data string.";
|
||||
|
||||
string actualHash = Security.SHA256Utility.Hash(rawData);
|
||||
string actualHash = Utilities.SHA256Utility.Hash(rawData);
|
||||
string expectedHash = "5bd1e86d96a5ec138242ee3c743ea004bc8e215ef8ab72178133a6460034f216";
|
||||
|
||||
Assert.Equal(expectedHash, actualHash, ignoreCase: true);
|
||||
|
@ -85,9 +85,9 @@ namespace SKIT.FlurlHttpClient.Wechat
|
||||
|
||||
if (name.EndsWith("Request"))
|
||||
{
|
||||
if (!typeof(IWechatRequest).IsAssignableFrom(modelType))
|
||||
if (!typeof(ICommonRequest).IsAssignableFrom(modelType))
|
||||
{
|
||||
lstError.Add(new Exception($"`{name}` 类需实现自 `IWechatRequest`。"));
|
||||
lstError.Add(new Exception($"`{name}` 类需实现自 `ICommonRequest`。"));
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -100,9 +100,9 @@ namespace SKIT.FlurlHttpClient.Wechat
|
||||
|
||||
if (name.EndsWith("Response"))
|
||||
{
|
||||
if (!typeof(IWechatResponse).IsAssignableFrom(modelType))
|
||||
if (!typeof(ICommonResponse).IsAssignableFrom(modelType))
|
||||
{
|
||||
lstError.Add(new Exception($"`{name}` 类需实现自 `IWechatResponse`。"));
|
||||
lstError.Add(new Exception($"`{name}` 类需实现自 `ICommonResponse`。"));
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -252,7 +252,7 @@ namespace SKIT.FlurlHttpClient.Wechat
|
||||
.Where(e =>
|
||||
e.IsPublic &&
|
||||
e.IsStatic &&
|
||||
typeof(IWechatClient).IsAssignableFrom(e.GetParameters().FirstOrDefault().ParameterType)
|
||||
typeof(ICommonClient).IsAssignableFrom(e.GetParameters().FirstOrDefault().ParameterType)
|
||||
)
|
||||
.ToArray();
|
||||
|
||||
@ -267,10 +267,10 @@ namespace SKIT.FlurlHttpClient.Wechat
|
||||
continue;
|
||||
}
|
||||
|
||||
// 第二个参数必为 IWechatRequest 子类
|
||||
if (!typeof(IWechatRequest).IsAssignableFrom(lstParamInfo[1].ParameterType))
|
||||
// 第二个参数必为 ICommonRequest 子类
|
||||
if (!typeof(ICommonRequest).IsAssignableFrom(lstParamInfo[1].ParameterType))
|
||||
{
|
||||
lstError.Add(new Exception($"`{extType.Name}.{methodInfo.Name}` 方法第 1 个入参需实现自 `IWechatRequest`。"));
|
||||
lstError.Add(new Exception($"`{extType.Name}.{methodInfo.Name}` 方法第 1 个入参需实现自 `ICommonRequest`。"));
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -1,12 +1,12 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netcoreapp3.1</TargetFramework>
|
||||
<TargetFrameworks>netcoreapp3.1; net6.0</TargetFrameworks>
|
||||
<LangVersion>8.0</LangVersion>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\src\SKIT.FlurlHttpClient.Wechat\SKIT.FlurlHttpClient.Wechat.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="SKIT.FlurlHttpClient.Common" Version="2.0.0" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
@ -1,7 +1,7 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netcoreapp3.1</TargetFramework>
|
||||
<TargetFrameworks>netcoreapp3.1; net6.0</TargetFrameworks>
|
||||
<LangVersion>8.0</LangVersion>
|
||||
</PropertyGroup>
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user