mirror of
https://gitee.com/fudiwei/DotNetCore.SKIT.FlurlHttpClient.Wechat.git
synced 2025-09-20 18:48:10 +08:00
feat: 升级公共组件
This commit is contained in:
@@ -9,6 +9,7 @@ using Flurl.Http;
|
||||
|
||||
namespace SKIT.FlurlHttpClient.Wechat.Ads
|
||||
{
|
||||
using SKIT.FlurlHttpClient;
|
||||
using SKIT.FlurlHttpClient.Primitives;
|
||||
|
||||
public static class WechatAdsClientExecuteImagesExtensions
|
||||
@@ -32,7 +33,7 @@ namespace SKIT.FlurlHttpClient.Wechat.Ads
|
||||
request.FileHash = EncodedString.ToHexString(Utilities.MD5Utility.Hash(request.FileBytes ?? Array.Empty<byte>())).Value!;
|
||||
|
||||
if (request.FileContentType is null)
|
||||
request.FileContentType = Utilities.FileNameToContentTypeMapper.GetContentTypeForImage(request.FileName!) ?? "image/png";
|
||||
request.FileContentType = MimeTypes.GetMimeMapping(request.FileName!);
|
||||
|
||||
string boundary = "--BOUNDARY--" + DateTimeOffset.Now.Ticks.ToString("x");
|
||||
using var fileContent = new ByteArrayContent(request.FileBytes ?? Array.Empty<byte>());
|
||||
|
@@ -36,11 +36,7 @@
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Reference Include="System.Web" Condition="'$(TargetFramework)' == 'net462'" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="SKIT.FlurlHttpClient.Common" Version="3.0.0" />
|
||||
<PackageReference Include="SKIT.FlurlHttpClient.Common" Version="3.1.0" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
@@ -4,6 +4,7 @@ using System.Xml.Linq;
|
||||
|
||||
namespace SKIT.FlurlHttpClient.Wechat.Api
|
||||
{
|
||||
using SKIT.FlurlHttpClient.Internal;
|
||||
using SKIT.FlurlHttpClient.Primitives;
|
||||
|
||||
/// <summary>
|
||||
@@ -136,7 +137,7 @@ namespace SKIT.FlurlHttpClient.Wechat.Api
|
||||
|
||||
try
|
||||
{
|
||||
xml = Utilities.XmlHelper.Serialize(webhookEvent);
|
||||
xml = _XmlSimpleSerializer.Serialize(webhookEvent, typeof(TEvent));
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@@ -367,7 +368,7 @@ namespace SKIT.FlurlHttpClient.Wechat.Api
|
||||
webhookXml = Utilities.WxMsgCryptor.AESDecrypt(cipherText: encryptedXml, encodingAESKey: client.Credentials.PushEncodingAESKey!, out _);
|
||||
}
|
||||
|
||||
return Utilities.XmlHelper.Deserialize<TEvent>(webhookXml);
|
||||
return (TEvent)_XmlSimpleSerializer.Deserialize(webhookXml, typeof(TEvent));
|
||||
}
|
||||
catch (WechatApiException)
|
||||
{
|
||||
|
@@ -401,7 +401,7 @@ namespace SKIT.FlurlHttpClient.Wechat.Api
|
||||
.CreateFlurlRequest(request, HttpMethod.Post, "card", "invoice", "platform", "setpdf")
|
||||
.SetQueryParam("access_token", request.AccessToken);
|
||||
|
||||
using var httpContent = Utilities.FileHttpContentBuilder.Build(fileName: "invoice.pdf", fileBytes: request.FileBytes, fileContentType: "application/pdf", formDataName: "pdf");
|
||||
using var httpContent = Utilities.HttpContentBuilder.BuildWithFile(fileName: "invoice.pdf", fileBytes: request.FileBytes, fileContentType: "application/pdf", formDataName: "pdf");
|
||||
return await client.SendFlurlRequestAsync<Models.CardInvoicePlatformSetPdfResponse>(flurlReq, httpContent: httpContent, cancellationToken: cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
|
@@ -430,7 +430,7 @@ namespace SKIT.FlurlHttpClient.Wechat.Api
|
||||
.CreateFlurlRequest(request, HttpMethod.Post, "cgi-bin", "component", "uploadprivacyextfile")
|
||||
.SetQueryParam("access_token", request.AccessToken);
|
||||
|
||||
using var httpContent = Utilities.FileHttpContentBuilder.Build(fileName: request.FileName, fileBytes: request.FileBytes, fileContentType: request.FileContentType, formDataName: "file");
|
||||
using var httpContent = Utilities.HttpContentBuilder.BuildWithFile(fileName: request.FileName, fileBytes: request.FileBytes, fileContentType: request.FileContentType, formDataName: "file");
|
||||
return await client.SendFlurlRequestAsync<Models.CgibinComponentUploadPrivacyExtraFileResponse>(flurlReq, httpContent: httpContent, cancellationToken: cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
|
@@ -8,6 +8,8 @@ using Flurl.Http;
|
||||
|
||||
namespace SKIT.FlurlHttpClient.Wechat.Api
|
||||
{
|
||||
using SKIT.FlurlHttpClient;
|
||||
|
||||
public static class WechatApiClientExecuteCgibinMaterialExtensions
|
||||
{
|
||||
/// <summary>
|
||||
@@ -47,23 +49,14 @@ namespace SKIT.FlurlHttpClient.Wechat.Api
|
||||
}
|
||||
|
||||
if (request.FileContentType is null)
|
||||
{
|
||||
if (TYPE_IMAGE.Equals(request.Type) || TYPE_THUMB.Equals(request.Type))
|
||||
request.FileContentType = Utilities.FileNameToContentTypeMapper.GetContentTypeForImage(request.FileName!) ?? "image/png";
|
||||
else if (TYPE_VOICE.Equals(request.Type))
|
||||
request.FileContentType = Utilities.FileNameToContentTypeMapper.GetContentTypeForVoice(request.FileName!) ?? "audio/mp3";
|
||||
else if (TYPE_VIDEO.Equals(request.Type))
|
||||
request.FileContentType = Utilities.FileNameToContentTypeMapper.GetContentTypeForVideo(request.FileName!) ?? "video/mp4";
|
||||
else
|
||||
request.FileContentType = "application/octet-stream";
|
||||
}
|
||||
request.FileContentType = MimeTypes.GetMimeMapping(request.FileName!);
|
||||
|
||||
IFlurlRequest flurlReq = client
|
||||
.CreateFlurlRequest(request, HttpMethod.Post, "cgi-bin", "material", "add_material")
|
||||
.SetQueryParam("access_token", request.AccessToken)
|
||||
.SetQueryParam("type", request.Type);
|
||||
|
||||
using var httpContent = Utilities.FileHttpContentBuilder.Build(fileName: request.FileName, fileBytes: request.FileBytes, fileContentType: request.FileContentType, formDataName: "media");
|
||||
using var httpContent = Utilities.HttpContentBuilder.BuildWithFile(fileName: request.FileName, fileBytes: request.FileBytes, fileContentType: request.FileContentType, formDataName: "media");
|
||||
if (TYPE_VIDEO.Equals(request.Type))
|
||||
{
|
||||
httpContent.Add(new StringContent(client.JsonSerializer.Serialize(request), Encoding.UTF8), "\"description\"");
|
||||
|
@@ -8,6 +8,8 @@ using Flurl.Http;
|
||||
|
||||
namespace SKIT.FlurlHttpClient.Wechat.Api
|
||||
{
|
||||
using SKIT.FlurlHttpClient;
|
||||
|
||||
public static class WechatApiClientExecuteCgibinMediaExtensions
|
||||
{
|
||||
/// <summary>
|
||||
@@ -48,23 +50,14 @@ namespace SKIT.FlurlHttpClient.Wechat.Api
|
||||
}
|
||||
|
||||
if (request.FileContentType is null)
|
||||
{
|
||||
if (TYPE_IMAGE.Equals(request.Type) || TYPE_THUMB.Equals(request.Type))
|
||||
request.FileContentType = Utilities.FileNameToContentTypeMapper.GetContentTypeForImage(request.FileName!) ?? "image/png";
|
||||
else if (TYPE_VOICE.Equals(request.Type))
|
||||
request.FileContentType = Utilities.FileNameToContentTypeMapper.GetContentTypeForVoice(request.FileName!) ?? "audio/mp3";
|
||||
else if (TYPE_VIDEO.Equals(request.Type))
|
||||
request.FileContentType = Utilities.FileNameToContentTypeMapper.GetContentTypeForVideo(request.FileName!) ?? "video/mp4";
|
||||
else
|
||||
request.FileContentType = "application/octet-stream";
|
||||
}
|
||||
request.FileContentType = MimeTypes.GetMimeMapping(request.FileName!);
|
||||
|
||||
IFlurlRequest flurlReq = client
|
||||
.CreateFlurlRequest(request, HttpMethod.Post, "cgi-bin", "media", "upload")
|
||||
.SetQueryParam("access_token", request.AccessToken)
|
||||
.SetQueryParam("type", request.Type);
|
||||
|
||||
using var httpContent = Utilities.FileHttpContentBuilder.Build(fileName: request.FileName, fileBytes: request.FileBytes, fileContentType: request.FileContentType, formDataName: "media");
|
||||
using var httpContent = Utilities.HttpContentBuilder.BuildWithFile(fileName: request.FileName, fileBytes: request.FileBytes, fileContentType: request.FileContentType, formDataName: "media");
|
||||
return await client.SendFlurlRequestAsync<Models.CgibinMediaUploadResponse>(flurlReq, httpContent: httpContent, cancellationToken: cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
@@ -116,13 +109,13 @@ namespace SKIT.FlurlHttpClient.Wechat.Api
|
||||
request.FileName = Guid.NewGuid().ToString("N").ToLower() + ".png";
|
||||
|
||||
if (request.FileContentType is null)
|
||||
request.FileContentType = Utilities.FileNameToContentTypeMapper.GetContentTypeForImage(request.FileName!) ?? "image/png";
|
||||
request.FileContentType = MimeTypes.GetMimeMapping(request.FileName!);
|
||||
|
||||
IFlurlRequest flurlReq = client
|
||||
.CreateFlurlRequest(request, HttpMethod.Post, "cgi-bin", "media", "uploadimg")
|
||||
.SetQueryParam("access_token", request.AccessToken);
|
||||
|
||||
using var httpContent = Utilities.FileHttpContentBuilder.Build(fileName: request.FileName, fileBytes: request.FileBytes, fileContentType: request.FileContentType, formDataName: "media");
|
||||
using var httpContent = Utilities.HttpContentBuilder.BuildWithFile(fileName: request.FileName, fileBytes: request.FileBytes, fileContentType: request.FileContentType, formDataName: "media");
|
||||
return await client.SendFlurlRequestAsync<Models.CgibinMediaUploadImageResponse>(flurlReq, httpContent: httpContent, cancellationToken: cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
|
@@ -280,7 +280,7 @@ namespace SKIT.FlurlHttpClient.Wechat.Api
|
||||
.SetQueryParam("height", request.Height)
|
||||
.SetQueryParam("width", request.Width);
|
||||
|
||||
using var httpContent = Utilities.FileHttpContentBuilder.Build(fileName: "image.png", fileBytes: request.ImageFileBytes!, fileContentType: "image/png", formDataName: "media");
|
||||
using var httpContent = Utilities.HttpContentBuilder.BuildWithFile(fileName: "image.png", fileBytes: request.ImageFileBytes!, fileContentType: "image/png", formDataName: "media");
|
||||
return await client.SendFlurlRequestAsync<Models.ChannelsECBasicsImageUploadResponse>(flurlReq, httpContent: httpContent, cancellationToken: cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
@@ -328,13 +328,13 @@ namespace SKIT.FlurlHttpClient.Wechat.Api
|
||||
request.FileName = Guid.NewGuid().ToString("N").ToLower() + ".png";
|
||||
|
||||
if (request.FileContentType is null)
|
||||
request.FileContentType = Utilities.FileNameToContentTypeMapper.GetContentTypeForImage(request.FileName!) ?? "image/png";
|
||||
request.FileContentType = MimeTypes.GetMimeMapping(request.FileName!);
|
||||
|
||||
IFlurlRequest flurlReq = client
|
||||
.CreateFlurlRequest(request, HttpMethod.Post, "channels", "ec", "basics", "qualification", "upload")
|
||||
.SetQueryParam("access_token", request.AccessToken);
|
||||
|
||||
using var httpContent = Utilities.FileHttpContentBuilder.Build(fileName: request.FileName, fileBytes: request.FileBytes, fileContentType: request.FileContentType, formDataName: "media");
|
||||
using var httpContent = Utilities.HttpContentBuilder.BuildWithFile(fileName: request.FileName, fileBytes: request.FileBytes, fileContentType: request.FileContentType, formDataName: "media");
|
||||
return await client.SendFlurlRequestAsync<Models.ChannelsECBasicsQualificationUploadResponse>(flurlReq, httpContent: httpContent, cancellationToken: cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
|
@@ -128,7 +128,7 @@ namespace SKIT.FlurlHttpClient.Wechat.Api
|
||||
.SetQueryParam("access_token", request.AccessToken)
|
||||
.SetQueryParam("kf_account", request.KfAccount);
|
||||
|
||||
using var httpContent = Utilities.FileHttpContentBuilder.Build(fileName: "image.jpg", fileBytes: request.HeadImageFileBytes, fileContentType: "image/jpeg", formDataName: "media");
|
||||
using var httpContent = Utilities.HttpContentBuilder.BuildWithFile(fileName: "image.jpg", fileBytes: request.HeadImageFileBytes, fileContentType: "image/jpeg", formDataName: "media");
|
||||
return await client.SendFlurlRequestAsync<Models.CustomServiceKfAccountUploadHeadImageResponse>(flurlReq, httpContent: httpContent, cancellationToken: cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
|
@@ -44,7 +44,7 @@ namespace SKIT.FlurlHttpClient.Wechat.Api
|
||||
.SetQueryParam("height", request.Height)
|
||||
.SetQueryParam("width", request.Width);
|
||||
|
||||
using var httpContent = Utilities.FileHttpContentBuilder.Build(fileName: "image.png", fileBytes: request.ImageFileBytes!, fileContentType: "image/png", formDataName: "media");
|
||||
using var httpContent = Utilities.HttpContentBuilder.BuildWithFile(fileName: "image.png", fileBytes: request.ImageFileBytes!, fileContentType: "image/png", formDataName: "media");
|
||||
return await client.SendFlurlRequestAsync<Models.ProductImageUploadResponse>(flurlReq, httpContent: httpContent, cancellationToken: cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
|
@@ -41,7 +41,7 @@ namespace SKIT.FlurlHttpClient.Wechat.Api
|
||||
{
|
||||
flurlReq.SetQueryParam("upload_type", 0);
|
||||
|
||||
using var httpContent = Utilities.FileHttpContentBuilder.Build(fileName: "image.png", fileBytes: request.ImageFileBytes!, fileContentType: "image/png", formDataName: "media");
|
||||
using var httpContent = Utilities.HttpContentBuilder.BuildWithFile(fileName: "image.png", fileBytes: request.ImageFileBytes!, fileContentType: "image/png", formDataName: "media");
|
||||
return await client.SendFlurlRequestAsync<Models.ShopImageUploadResponse>(flurlReq, httpContent: httpContent, cancellationToken: cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
|
@@ -8,6 +8,8 @@ using Flurl.Http;
|
||||
|
||||
namespace SKIT.FlurlHttpClient.Wechat.Api
|
||||
{
|
||||
using SKIT.FlurlHttpClient;
|
||||
|
||||
public static class WechatApiClientExecuteWxaComponentExtensions
|
||||
{
|
||||
#region AMS
|
||||
@@ -1120,23 +1122,16 @@ namespace SKIT.FlurlHttpClient.Wechat.Api
|
||||
if (request is null) throw new ArgumentNullException(nameof(request));
|
||||
|
||||
if (request.FileName is null)
|
||||
{
|
||||
request.FileName = Guid.NewGuid().ToString("N").ToLower();
|
||||
}
|
||||
|
||||
if (request.FileContentType is null)
|
||||
{
|
||||
request.FileContentType =
|
||||
Utilities.FileNameToContentTypeMapper.GetContentTypeForImage(request.FileName!) ??
|
||||
Utilities.FileNameToContentTypeMapper.GetContentTypeForVideo(request.FileName!) ??
|
||||
"application/octet-stream";
|
||||
}
|
||||
request.FileContentType = MimeTypes.GetMimeMapping(request.FileName!);
|
||||
|
||||
IFlurlRequest flurlReq = client
|
||||
.CreateFlurlRequest(request, HttpMethod.Post, "wxa", "uploadmedia")
|
||||
.SetQueryParam("access_token", request.AccessToken);
|
||||
|
||||
using var httpContent = Utilities.FileHttpContentBuilder.Build(fileName: request.FileName, fileBytes: request.FileBytes, fileContentType: request.FileContentType, formDataName: "media");
|
||||
using var httpContent = Utilities.HttpContentBuilder.BuildWithFile(fileName: request.FileName, fileBytes: request.FileBytes, fileContentType: request.FileContentType, formDataName: "media");
|
||||
return await client.SendFlurlRequestAsync<Models.WxaUploadMediaResponse>(flurlReq, httpContent: httpContent, cancellationToken: cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
#endregion
|
||||
@@ -1428,20 +1423,13 @@ namespace SKIT.FlurlHttpClient.Wechat.Api
|
||||
}
|
||||
|
||||
if (request.FileContentType is null)
|
||||
{
|
||||
if (TYPE_IMAGE.Equals(request.Type))
|
||||
request.FileContentType = Utilities.FileNameToContentTypeMapper.GetContentTypeForImage(request.FileName!) ?? "image/png";
|
||||
else if (TYPE_VIDEO.Equals(request.Type))
|
||||
request.FileContentType = Utilities.FileNameToContentTypeMapper.GetContentTypeForVideo(request.FileName!) ?? "video/mp4";
|
||||
else
|
||||
request.FileContentType = "application/octet-stream";
|
||||
}
|
||||
request.FileContentType = MimeTypes.GetMimeMapping(request.FileName!);
|
||||
|
||||
IFlurlRequest flurlReq = client
|
||||
.CreateFlurlRequest(request, HttpMethod.Post, "wxa", "icp", "upload_icp_media")
|
||||
.SetQueryParam("access_token", request.AccessToken);
|
||||
|
||||
using var httpContent = Utilities.FileHttpContentBuilder.Build(fileName: request.FileName, fileBytes: request.FileBytes, fileContentType: request.FileContentType, formDataName: "media");
|
||||
using var httpContent = Utilities.HttpContentBuilder.BuildWithFile(fileName: request.FileName, fileBytes: request.FileBytes, fileContentType: request.FileContentType, formDataName: "media");
|
||||
httpContent.Add(new StringContent(request.Type, Encoding.UTF8), "\"type\"");
|
||||
httpContent.Add(new StringContent(request.ICPOrderField, Encoding.UTF8), "\"icp_order_field\"");
|
||||
if (request.CertificateType is not null) httpContent.Add(new StringContent(request.CertificateType.ToString()!, Encoding.UTF8), "\"certificate_type\"");
|
||||
|
@@ -668,7 +668,7 @@ namespace SKIT.FlurlHttpClient.Wechat.Api
|
||||
.CreateFlurlRequest(request, HttpMethod.Post, "wxa", "imagesearch")
|
||||
.SetQueryParam("access_token", request.AccessToken);
|
||||
|
||||
using var httpContent = Utilities.FileHttpContentBuilder.Build(fileName: "image.png", fileBytes: request.ImageFileBytes, fileContentType: "image/png", formDataName: "img");
|
||||
using var httpContent = Utilities.HttpContentBuilder.BuildWithFile(fileName: "image.png", fileBytes: request.ImageFileBytes, fileContentType: "image/png", formDataName: "img");
|
||||
return await client.SendFlurlRequestAsync<Models.WxaImageSearchResponse>(flurlReq, httpContent: httpContent, cancellationToken: cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
@@ -741,7 +741,7 @@ namespace SKIT.FlurlHttpClient.Wechat.Api
|
||||
.CreateFlurlRequest(request, HttpMethod.Post, "wxa", "img_sec_check")
|
||||
.SetQueryParam("access_token", request.AccessToken);
|
||||
|
||||
using var httpContent = Utilities.FileHttpContentBuilder.Build(fileName: "image.png", fileBytes: request.FileBytes, fileContentType: "image/png", formDataName: "media");
|
||||
using var httpContent = Utilities.HttpContentBuilder.BuildWithFile(fileName: "image.png", fileBytes: request.FileBytes, fileContentType: "image/png", formDataName: "media");
|
||||
return await client.SendFlurlRequestAsync<Models.WxaImageSecurityCheckResponse>(flurlReq, httpContent: httpContent, cancellationToken: cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
|
@@ -99,7 +99,7 @@ namespace SKIT.FlurlHttpClient.Wechat.Api
|
||||
.CreateFlurlRequest(request, HttpMethod.Post, "wxa", "sec", "uploadauthmaterial")
|
||||
.SetQueryParam("access_token", request.AccessToken);
|
||||
|
||||
using var httpContent = Utilities.FileHttpContentBuilder.Build(fileName: "media.png", fileBytes: request.FileBytes, fileContentType: "image/png", formDataName: "media");
|
||||
using var httpContent = Utilities.HttpContentBuilder.BuildWithFile(fileName: "media.png", fileBytes: request.FileBytes, fileContentType: "image/png", formDataName: "media");
|
||||
return await client.SendFlurlRequestAsync<Models.WxaSecUploadAuthMaterialResponse>(flurlReq, httpContent: httpContent, cancellationToken: cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
@@ -435,7 +435,7 @@ namespace SKIT.FlurlHttpClient.Wechat.Api
|
||||
.CreateFlurlRequest(request, HttpMethod.Post, "wxa", "sec", "vod", "singlefileupload")
|
||||
.SetQueryParam("access_token", request.AccessToken);
|
||||
|
||||
using var httpContent = Utilities.FileHttpContentBuilder.Build(fileName: $"{request.MediaName}.{request.MediaType}", fileBytes: request.MediaFileBytes, fileContentType: "video/mp4", formDataName: "media_data");
|
||||
using var httpContent = Utilities.HttpContentBuilder.BuildWithFile(fileName: $"{request.MediaName}.{request.MediaType}", fileBytes: request.MediaFileBytes, fileContentType: "video/mp4", formDataName: "media_data");
|
||||
if (request.CoverType is not null) httpContent.Add(new StringContent(request.CoverType), "cover_type");
|
||||
if (request.CoverFileBytes is not null) httpContent.Add(new ByteArrayContent(request.CoverFileBytes), "cover_data");
|
||||
if (request.SourceContext is not null) httpContent.Add(new StringContent(request.SourceContext), "source_context");
|
||||
@@ -531,7 +531,7 @@ namespace SKIT.FlurlHttpClient.Wechat.Api
|
||||
.CreateFlurlRequest(request, HttpMethod.Post, "wxa", "sec", "vod", "uploadpart")
|
||||
.SetQueryParam("access_token", request.AccessToken);
|
||||
|
||||
using var httpContent = Utilities.FileHttpContentBuilder.Build(fileName: string.Empty, fileBytes: request.FileBytes, fileContentType: "application/octet-stream", formDataName: "data");
|
||||
using var httpContent = Utilities.HttpContentBuilder.BuildWithFile(fileName: string.Empty, fileBytes: request.FileBytes, fileContentType: "application/octet-stream", formDataName: "data");
|
||||
httpContent.Add(new StringContent(request.UploadId), "upload_id");
|
||||
httpContent.Add(new StringContent(request.PartNumber.ToString()), "part_number");
|
||||
httpContent.Add(new StringContent(request.FileType.ToString()), "resource_type");
|
||||
|
@@ -35,13 +35,9 @@
|
||||
<None Include="README.md" Pack="true" PackagePath="/" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Reference Include="System.Web" Condition="'$(TargetFramework)' == 'net462'" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="BouncyCastle.Cryptography" Version="2.4.0" />
|
||||
<PackageReference Include="SKIT.FlurlHttpClient.Common" Version="3.0.0" />
|
||||
<PackageReference Include="SKIT.FlurlHttpClient.Common" Version="3.1.0" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
@@ -1,50 +0,0 @@
|
||||
using System.IO;
|
||||
|
||||
namespace SKIT.FlurlHttpClient.Wechat.Api.Utilities
|
||||
{
|
||||
internal static class FileNameToContentTypeMapper
|
||||
{
|
||||
public static string? GetContentTypeForImage(string fileName)
|
||||
{
|
||||
string extension = Path.GetExtension(fileName ?? "/")?.ToLower() ?? string.Empty;
|
||||
switch (extension)
|
||||
{
|
||||
case ".jpg":
|
||||
case ".jpeg":
|
||||
return "image/jpeg";
|
||||
case ".bmp":
|
||||
return "image/bmp";
|
||||
case ".png":
|
||||
return "image/png";
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static string? GetContentTypeForVoice(string fileName)
|
||||
{
|
||||
string extension = Path.GetExtension(fileName ?? "/")?.ToLower() ?? string.Empty;
|
||||
switch (extension)
|
||||
{
|
||||
case ".mp3":
|
||||
return "audio/mpeg";
|
||||
case ".amr":
|
||||
return "audio/amr";
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static string? GetContentTypeForVideo(string fileName)
|
||||
{
|
||||
string extension = Path.GetExtension(fileName ?? "/")?.ToLower() ?? string.Empty;
|
||||
switch (extension)
|
||||
{
|
||||
case ".mp4":
|
||||
return "video/mp4";
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
@@ -5,22 +5,18 @@ using System.Text;
|
||||
|
||||
namespace SKIT.FlurlHttpClient.Wechat.Api.Utilities
|
||||
{
|
||||
internal static class FileHttpContentBuilder
|
||||
{
|
||||
public static MultipartFormDataContent Build(string fileName, byte[] fileBytes, string fileContentType, string formDataName)
|
||||
{
|
||||
return Build(fileName: fileName, fileBytes: fileBytes, fileContentType: fileContentType, formDataName: formDataName, (_) => { });
|
||||
}
|
||||
using SKIT.FlurlHttpClient;
|
||||
|
||||
public static MultipartFormDataContent Build(string fileName, byte[] fileBytes, string fileContentType, string formDataName, Action<HttpContent> configureFileHttpContent)
|
||||
internal static class HttpContentBuilder
|
||||
{
|
||||
public static MultipartFormDataContent BuildWithFile(string fileName, byte[] fileBytes, string? fileContentType, string formDataName, Action<HttpContent>? configureFileHttpContent = null)
|
||||
{
|
||||
if (fileName is null) throw new ArgumentNullException(nameof(fileName));
|
||||
if (formDataName is null) throw new ArgumentNullException(nameof(formDataName));
|
||||
if (configureFileHttpContent is null) throw new ArgumentNullException(nameof(configureFileHttpContent));
|
||||
|
||||
fileName = fileName.Replace("\"", string.Empty);
|
||||
fileBytes = fileBytes ?? Array.Empty<byte>();
|
||||
fileContentType = string.IsNullOrEmpty(fileContentType) ? "application/octet-stream" : fileContentType;
|
||||
fileContentType = string.IsNullOrEmpty(fileContentType) ? MimeTypes.Binary : fileContentType;
|
||||
formDataName = formDataName.Replace("\"", string.Empty);
|
||||
|
||||
// HACKED: 默认不支持 Unicode 文件名 https://github.com/dotnet/runtime/issues/22996
|
||||
@@ -33,11 +29,11 @@ namespace SKIT.FlurlHttpClient.Wechat.Api.Utilities
|
||||
fileContent.Headers.ContentDisposition = ContentDispositionHeaderValue.Parse($"form-data; name=\"{formDataName}\"; filename=\"{hackedFileName}\"");
|
||||
fileContent.Headers.ContentType = MediaTypeHeaderValue.Parse(fileContentType);
|
||||
fileContent.Headers.ContentLength = fileBytes.Length;
|
||||
configureFileHttpContent(fileContent);
|
||||
configureFileHttpContent?.Invoke(fileContent);
|
||||
|
||||
string boundary = "--BOUNDARY--" + DateTimeOffset.Now.Ticks.ToString("x");
|
||||
MultipartFormDataContent httpContent = new MultipartFormDataContent(boundary);
|
||||
httpContent.Headers.ContentType = MediaTypeHeaderValue.Parse($"multipart/form-data; boundary={boundary}");
|
||||
httpContent.Headers.ContentType = MediaTypeHeaderValue.Parse($"{MimeTypes.FormData}; boundary={boundary}");
|
||||
httpContent.Add(fileContent);
|
||||
return httpContent;
|
||||
}
|
@@ -1,31 +0,0 @@
|
||||
using System;
|
||||
|
||||
namespace SKIT.FlurlHttpClient.Wechat.Api.Utilities
|
||||
{
|
||||
using SKIT.FlurlHttpClient.Internal;
|
||||
|
||||
internal static class XmlHelper
|
||||
{
|
||||
public static string Serialize(object obj, Type type)
|
||||
{
|
||||
return _XmlSimpleSerializer.Serialize(obj, type);
|
||||
}
|
||||
|
||||
public static string Serialize<T>(T obj)
|
||||
where T : class
|
||||
{
|
||||
return Serialize(obj, typeof(T));
|
||||
}
|
||||
|
||||
public static object Deserialize(string xml, Type type)
|
||||
{
|
||||
return _XmlSimpleSerializer.Deserialize(xml, type);
|
||||
}
|
||||
|
||||
public static T Deserialize<T>(string xml)
|
||||
where T : class
|
||||
{
|
||||
return (T)Deserialize(xml, typeof(T));
|
||||
}
|
||||
}
|
||||
}
|
@@ -36,11 +36,7 @@
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Reference Include="System.Web" Condition="'$(TargetFramework)' == 'net462'" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="SKIT.FlurlHttpClient.Common" Version="3.0.0" />
|
||||
<PackageReference Include="SKIT.FlurlHttpClient.Common" Version="3.1.0" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
@@ -6,6 +6,7 @@ using Flurl.Http;
|
||||
|
||||
namespace SKIT.FlurlHttpClient.Wechat.TenpayBusiness
|
||||
{
|
||||
using SKIT.FlurlHttpClient;
|
||||
using SKIT.FlurlHttpClient.Primitives;
|
||||
|
||||
public static class WechatTenpayBusinessClientExecuteFileUploadsExtensions
|
||||
@@ -33,12 +34,12 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayBusiness
|
||||
request.FileHash = EncodedString.ToHexString(Utilities.SM3Utility.Hash(request.FileBytes)).Value!.ToLower();
|
||||
|
||||
if (request.FileContentType is null)
|
||||
request.FileContentType = Utilities.FileNameToContentTypeMapper.GetContentTypeForImage(request.FileName!) ?? "image/png";
|
||||
request.FileContentType = MimeTypes.GetMimeMapping(request.FileName!);
|
||||
|
||||
IFlurlRequest flurlReq = client
|
||||
.CreateFlurlRequest(request, HttpMethod.Post, "mse-pay", "file-uploads");
|
||||
|
||||
using var httpContent = Utilities.FileHttpContentBuilder.Build(fileName: request.FileName, fileBytes: request.FileBytes, fileContentType: request.FileContentType, fileMetaJson: client.JsonSerializer.Serialize(request));
|
||||
using var httpContent = Utilities.HttpContentBuilder.BuildWithFile(fileName: request.FileName, fileBytes: request.FileBytes, fileContentType: request.FileContentType, fileMetaJson: client.JsonSerializer.Serialize(request));
|
||||
return await client.SendFlurlRequestAsync<Models.UploadFileResponse>(flurlReq, httpContent: httpContent, cancellationToken: cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
|
@@ -1,7 +1,7 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFrameworks>net462; net471; netstandard2.0; net6.0</TargetFrameworks>
|
||||
<TargetFrameworks>net462; netstandard2.0; net6.0</TargetFrameworks>
|
||||
<LangVersion>10.0</LangVersion>
|
||||
<Nullable>enable</Nullable>
|
||||
<NullableReferenceTypes>true</NullableReferenceTypes>
|
||||
@@ -35,14 +35,10 @@
|
||||
<None Include="README.md" Pack="true" PackagePath="/" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Reference Include="System.Web" Condition="'$(TargetFramework)' == 'net462' Or '$(TargetFramework)' == 'net471'" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="BouncyCastle.Cryptography" Version="2.4.0" />
|
||||
<PackageReference Include="System.ValueTuple" Version="4.5.0" Condition="'$(TargetFramework)' == 'net462'" />
|
||||
<PackageReference Include="SKIT.FlurlHttpClient.Common" Version="3.0.0" />
|
||||
<PackageReference Include="SKIT.FlurlHttpClient.Common" Version="3.1.0" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
@@ -1,24 +0,0 @@
|
||||
using System.IO;
|
||||
|
||||
namespace SKIT.FlurlHttpClient.Wechat.TenpayBusiness.Utilities
|
||||
{
|
||||
internal static class FileNameToContentTypeMapper
|
||||
{
|
||||
public static string? GetContentTypeForImage(string fileName)
|
||||
{
|
||||
string extension = Path.GetExtension(fileName ?? "/")?.ToLower() ?? string.Empty;
|
||||
switch (extension)
|
||||
{
|
||||
case ".jpg":
|
||||
case ".jpeg":
|
||||
return "image/jpeg";
|
||||
case ".bmp":
|
||||
return "image/bmp";
|
||||
case ".png":
|
||||
return "image/png";
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,40 +1,34 @@
|
||||
using System;
|
||||
using System.Net.Http;
|
||||
using System.Net.Http.Headers;
|
||||
using System.Text;
|
||||
using System.Web;
|
||||
|
||||
namespace SKIT.FlurlHttpClient.Wechat.TenpayBusiness.Utilities
|
||||
{
|
||||
internal static class FileHttpContentBuilder
|
||||
{
|
||||
public static MultipartFormDataContent Build(string fileName, byte[] fileBytes, string fileContentType, string fileMetaJson, string formDataName = "file")
|
||||
{
|
||||
return Build(fileName: fileName, fileBytes: fileBytes, fileContentType: fileContentType, fileMetaJson: fileMetaJson, formDataName: formDataName, (_) => { }, (_) => { });
|
||||
}
|
||||
using SKIT.FlurlHttpClient;
|
||||
|
||||
public static MultipartFormDataContent Build(string fileName, byte[] fileBytes, string fileContentType, string fileMetaJson, string formDataName, Action<HttpContent> configureMetaHttpContent, Action<HttpContent> configureFileHttpContent)
|
||||
internal static class HttpContentBuilder
|
||||
{
|
||||
public static MultipartFormDataContent BuildWithFile(string fileName, byte[] fileBytes, string fileContentType, string fileMetaJson, string formDataName = "file", Action<HttpContent>? configureMetaHttpContent = null, Action<HttpContent>? configureFileHttpContent = null)
|
||||
{
|
||||
if (fileName is null) throw new ArgumentNullException(nameof(fileName));
|
||||
if (fileMetaJson is null) throw new ArgumentNullException(nameof(fileMetaJson));
|
||||
if (formDataName is null) throw new ArgumentNullException(nameof(formDataName));
|
||||
if (configureFileHttpContent is null) throw new ArgumentNullException(nameof(configureFileHttpContent));
|
||||
|
||||
fileBytes = fileBytes ?? Array.Empty<byte>();
|
||||
fileContentType = string.IsNullOrEmpty(fileContentType) ? "application/octet-stream" : fileContentType;
|
||||
fileContentType = string.IsNullOrEmpty(fileContentType) ? MimeTypes.Binary : fileContentType;
|
||||
formDataName = formDataName.Replace("\"", string.Empty);
|
||||
|
||||
ByteArrayContent metaContent = new ByteArrayContent(Encoding.UTF8.GetBytes(fileMetaJson));
|
||||
metaContent.Headers.ContentType = MediaTypeHeaderValue.Parse("application/json");
|
||||
configureMetaHttpContent(metaContent);
|
||||
StringContent metaContent = new StringContent(fileMetaJson, null, MimeTypes.Json);
|
||||
configureMetaHttpContent?.Invoke(metaContent);
|
||||
|
||||
ByteArrayContent fileContent = new ByteArrayContent(fileBytes);
|
||||
fileContent.Headers.ContentType = MediaTypeHeaderValue.Parse(fileContentType);
|
||||
configureFileHttpContent(fileContent);
|
||||
configureFileHttpContent?.Invoke(fileContent);
|
||||
|
||||
string boundary = "--BOUNDARY--" + DateTimeOffset.Now.Ticks.ToString("x");
|
||||
MultipartFormDataContent httpContent = new MultipartFormDataContent(boundary);
|
||||
httpContent.Headers.ContentType = MediaTypeHeaderValue.Parse($"multipart/form-data; boundary={boundary}");
|
||||
httpContent.Headers.ContentType = MediaTypeHeaderValue.Parse($"{MimeTypes.FormData}; boundary={boundary}");
|
||||
httpContent.Add(metaContent, $"\"{Constants.FormDataFields.FORMDATA_META}\"");
|
||||
httpContent.Add(fileContent, $"\"{formDataName}\"", $"\"{HttpUtility.UrlEncode(fileName)}\"");
|
||||
return httpContent;
|
@@ -36,8 +36,7 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV2
|
||||
|
||||
string xml = xmlDocument.InnerXml;
|
||||
string json = Utilities.XmlHelper.ConvertToJson(xml);
|
||||
string signData = Utilities.JsonHelper.ParseToSortedQueryString(json);
|
||||
string actualSign = Utilities.RequestSigner.SignFromSortedQueryString(signData, client.Credentials.MerchantSecret, signType);
|
||||
string actualSign = Utilities.RequestSigner.SignFromJson(json, client.Credentials.MerchantSecret, signType);
|
||||
|
||||
bool valid = string.Equals(expectedSign, actualSign, StringComparison.OrdinalIgnoreCase);
|
||||
if (valid)
|
||||
|
@@ -1,7 +1,7 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFrameworks>net461; net471; netstandard2.0; net6.0</TargetFrameworks>
|
||||
<TargetFrameworks>net462; net471; netstandard2.0; net6.0</TargetFrameworks>
|
||||
<LangVersion>10.0</LangVersion>
|
||||
<Nullable>enable</Nullable>
|
||||
<NullableReferenceTypes>true</NullableReferenceTypes>
|
||||
@@ -36,12 +36,12 @@
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Reference Include="System.Net.Http.WebRequest" Condition="'$(TargetFramework)' == 'net461' Or '$(TargetFramework)' == 'net471'" />
|
||||
<Reference Include="System.Web" Condition="'$(TargetFramework)' == 'net461' Or '$(TargetFramework)' == 'net471'" />
|
||||
<Reference Include="System.Net.Http.WebRequest" Condition="'$(TargetFramework.TrimEnd(`0123456789`))' == 'net'" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="SKIT.FlurlHttpClient.Common" Version="3.0.0" />
|
||||
<PackageReference Include="SKIT.FlurlHttpClient.Common" Version="3.1.0" />
|
||||
<PackageReference Include="System.Net.Http.WinHttpHandler" Version="8.0.1" Condition="'$(TargetFramework)' == 'netstandard2.0'" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
@@ -13,16 +13,22 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV2.Settings
|
||||
#if NETCOREAPP2_1_OR_GREATER || NET5_0_OR_GREATER
|
||||
SocketsHttpHandler handler = new SocketsHttpHandler();
|
||||
handler.SslOptions = new SslClientAuthenticationOptions() { RemoteCertificateValidationCallback = static (_, _, _, _) => true };
|
||||
#else
|
||||
#elif NET471_OR_GREATER
|
||||
HttpClientHandler handler = new HttpClientHandler();
|
||||
handler.ServerCertificateCustomValidationCallback = static (_, _, _, sslPolicyErrors) => sslPolicyErrors == SslPolicyErrors.None;
|
||||
#elif NET462_OR_GREATER
|
||||
WebRequestHandler handler = new WebRequestHandler();
|
||||
handler.ServerCertificateValidationCallback = static (_, _, _, _) => true;
|
||||
#else
|
||||
WinHttpHandler handler = new WinHttpHandler();
|
||||
handler.ServerCertificateValidationCallback = static (_, _, _, _) => true;
|
||||
#endif
|
||||
|
||||
if (certificateBytes is not null)
|
||||
{
|
||||
X509Certificate x509;
|
||||
|
||||
#if NET471_OR_GREATER || NETSTANDARD2_0_OR_GREATER || NET5_0_OR_GREATER
|
||||
#if NET471_OR_GREATER || NETCOREAPP2_1_OR_GREATER || NET5_0_OR_GREATER
|
||||
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
|
||||
#else
|
||||
if (Environment.OSVersion.Platform == PlatformID.Win32NT)
|
||||
|
@@ -1,30 +0,0 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Text.Json.Nodes;
|
||||
|
||||
namespace SKIT.FlurlHttpClient.Wechat.TenpayV2.Utilities
|
||||
{
|
||||
internal static class JsonHelper
|
||||
{
|
||||
internal static string ParseToSortedQueryString(string json)
|
||||
{
|
||||
if (string.IsNullOrEmpty(json))
|
||||
return string.Empty;
|
||||
|
||||
StringBuilder stringBuilder = new StringBuilder();
|
||||
JsonObject jObject = JsonNode.Parse(json)!.AsObject();
|
||||
foreach (KeyValuePair<string, JsonNode?> jProp in jObject.OrderBy(p => p.Key))
|
||||
{
|
||||
string key = jProp.Key;
|
||||
string? value = jProp.Value?.ToString();
|
||||
if (string.IsNullOrEmpty(value))
|
||||
continue;
|
||||
|
||||
stringBuilder.Append($"{key}={value}&");
|
||||
}
|
||||
|
||||
return stringBuilder.ToString().TrimEnd('&');
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,6 +1,8 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Text.Json.Nodes;
|
||||
|
||||
namespace SKIT.FlurlHttpClient.Wechat.TenpayV2.Utilities
|
||||
{
|
||||
@@ -29,7 +31,20 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV2.Utilities
|
||||
|
||||
public static string SignFromJson(string json, string secretKey, string secretValue, string? signType = null)
|
||||
{
|
||||
return SignFromSortedQueryString(queryString: JsonHelper.ParseToSortedQueryString(json), secretKey: secretKey, secretValue: secretValue, signType: signType);
|
||||
StringBuilder stringBuilder = new StringBuilder();
|
||||
JsonObject jObject = JsonNode.Parse(json)!.AsObject();
|
||||
foreach (KeyValuePair<string, JsonNode?> jProp in jObject.OrderBy(p => p.Key))
|
||||
{
|
||||
string key = jProp.Key;
|
||||
string? value = jProp.Value?.ToString();
|
||||
if (string.IsNullOrEmpty(value))
|
||||
continue;
|
||||
|
||||
stringBuilder.Append($"{key}={value}&");
|
||||
}
|
||||
|
||||
string sortedQueryString = stringBuilder.ToString().TrimEnd('&');
|
||||
return SignFromSortedQueryString(queryString: sortedQueryString, secretKey: secretKey, secretValue: secretValue, signType: signType);
|
||||
}
|
||||
|
||||
public static string SignFromSortedQueryString(string queryString, string secret, string? signType = null)
|
||||
|
@@ -3,10 +3,12 @@ using System.Net.Http;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Flurl.Http;
|
||||
using SKIT.FlurlHttpClient.Primitives;
|
||||
|
||||
namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.ExtendedSDK.Global
|
||||
{
|
||||
using SKIT.FlurlHttpClient;
|
||||
using SKIT.FlurlHttpClient.Primitives;
|
||||
|
||||
public static class WechatTenpayGlobalClientExecuteMerchantsExtensions
|
||||
{
|
||||
/// <summary>
|
||||
@@ -110,12 +112,12 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.ExtendedSDK.Global
|
||||
request.FileHash = EncodedString.ToHexString(Utilities.SHA256Utility.Hash(request.FileBytes)).Value!.ToLower();
|
||||
|
||||
if (request.FileContentType is null)
|
||||
request.FileContentType = Utilities.FileNameToContentTypeMapper.GetContentTypeForImage(request.FileName!) ?? "image/jpeg";
|
||||
request.FileContentType = MimeTypes.GetMimeMapping(request.FileName!);
|
||||
|
||||
IFlurlRequest flurlReq = client
|
||||
.CreateFlurlRequest(request, HttpMethod.Post, "merchant", "media", "upload");
|
||||
|
||||
using var httpContent = Utilities.FileHttpContentBuilder.Build(fileName: request.FileName, fileBytes: request.FileBytes, fileContentType: request.FileContentType, fileMetaJson: client.JsonSerializer.Serialize(request));
|
||||
using var httpContent = Utilities.HttpContentBuilder.BuildWithFile(fileName: request.FileName, fileBytes: request.FileBytes, fileContentType: request.FileContentType, fileMetaJson: client.JsonSerializer.Serialize(request));
|
||||
return await client.SendFlurlRequestAsync<Models.UploadMerchantMediaImageResponse>(flurlReq, httpContent: httpContent, cancellationToken: cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
|
@@ -5,11 +5,5 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.ExtendedSDK.Global.Models
|
||||
/// </summary>
|
||||
public class UpdateMerchantH5PermissionApplicationResponse : GetMerchantH5PermissionApplicationByApplymentIdResponse
|
||||
{
|
||||
/// <summary>
|
||||
/// 获取或设置申请单 ID。
|
||||
/// </summary>
|
||||
[Newtonsoft.Json.JsonIgnore]
|
||||
[System.Text.Json.Serialization.JsonIgnore]
|
||||
public string ApplymentId { get; set; } = string.Empty;
|
||||
}
|
||||
}
|
||||
|
@@ -5,11 +5,5 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.ExtendedSDK.Global.Models
|
||||
/// </summary>
|
||||
public class UpdateMerchantH5PermissionDomainApplicationResponse : GetMerchantH5PermissionDomainApplicationByApplymentIdResponse
|
||||
{
|
||||
/// <summary>
|
||||
/// 获取或设置申请单 ID。
|
||||
/// </summary>
|
||||
[Newtonsoft.Json.JsonIgnore]
|
||||
[System.Text.Json.Serialization.JsonIgnore]
|
||||
public string ApplymentId { get; set; } = string.Empty;
|
||||
}
|
||||
}
|
||||
|
@@ -6,6 +6,7 @@ using Flurl.Http;
|
||||
|
||||
namespace SKIT.FlurlHttpClient.Wechat.TenpayV3
|
||||
{
|
||||
using SKIT.FlurlHttpClient;
|
||||
using SKIT.FlurlHttpClient.Primitives;
|
||||
|
||||
public static class WechatTenpayClientExecuteEcommerceExtensions
|
||||
@@ -78,12 +79,12 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3
|
||||
request.FileHash = EncodedString.ToHexString(Utilities.SHA256Utility.Hash(request.FileBytes)).Value!.ToLower();
|
||||
|
||||
if (request.FileContentType is null)
|
||||
request.FileContentType = Utilities.FileNameToContentTypeMapper.GetContentTypeForImage(request.FileName!) ?? "image/png";
|
||||
request.FileContentType = MimeTypes.GetMimeMapping(request.FileName!);
|
||||
|
||||
IFlurlRequest flurlReq = client
|
||||
.CreateFlurlRequest(request, HttpMethod.Post, "ecommerce", "account", "cancel-applications", "media");
|
||||
|
||||
using var httpContent = Utilities.FileHttpContentBuilder.Build(fileName: request.FileName, fileBytes: request.FileBytes, fileContentType: request.FileContentType, fileMetaJson: client.JsonSerializer.Serialize(request));
|
||||
using var httpContent = Utilities.HttpContentBuilder.BuildWithFile(fileName: request.FileName, fileBytes: request.FileBytes, fileContentType: request.FileContentType, fileMetaJson: client.JsonSerializer.Serialize(request));
|
||||
return await client.SendFlurlRequestAsync<Models.UploadEcommerceAccountCancelApplicationMediaResponse>(flurlReq, httpContent: httpContent, cancellationToken: cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
#endregion
|
||||
|
@@ -6,6 +6,7 @@ using Flurl.Http;
|
||||
|
||||
namespace SKIT.FlurlHttpClient.Wechat.TenpayV3
|
||||
{
|
||||
using SKIT.FlurlHttpClient;
|
||||
using SKIT.FlurlHttpClient.Primitives;
|
||||
|
||||
public static class WechatTenpayClientExecuteMarketingBankExtensions
|
||||
@@ -34,12 +35,12 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3
|
||||
request.FileHash = EncodedString.ToHexString(Utilities.SHA256Utility.Hash(request.FileBytes ?? Array.Empty<byte>())).Value!.ToLower();
|
||||
|
||||
if (request.FileContentType is null)
|
||||
request.FileContentType = Utilities.FileNameToContentTypeMapper.GetContentTypeForImage(request.FileName!) ?? "text/plain";
|
||||
request.FileContentType = MimeTypes.GetMimeMapping(request.FileName!);
|
||||
|
||||
IFlurlRequest flurlReq = client
|
||||
.CreateFlurlRequest(request, HttpMethod.Post, "marketing", "bank", "packages", request.PackageId, "tasks");
|
||||
|
||||
using var httpContent = Utilities.FileHttpContentBuilder.Build(fileName: request.FileName, fileBytes: request.FileBytes!, fileContentType: request.FileContentType, fileMetaJson: client.JsonSerializer.Serialize(request));
|
||||
using var httpContent = Utilities.HttpContentBuilder.BuildWithFile(fileName: request.FileName, fileBytes: request.FileBytes!, fileContentType: request.FileContentType, fileMetaJson: client.JsonSerializer.Serialize(request));
|
||||
return await client.SendFlurlRequestAsync<Models.UploadMarketingBankPackagesTasksResponse>(flurlReq, httpContent: httpContent, cancellationToken: cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
|
@@ -6,6 +6,7 @@ using Flurl.Http;
|
||||
|
||||
namespace SKIT.FlurlHttpClient.Wechat.TenpayV3
|
||||
{
|
||||
using SKIT.FlurlHttpClient;
|
||||
using SKIT.FlurlHttpClient.Primitives;
|
||||
|
||||
public static class WechatTenpayClientExecuteMarketingMediaExtensions
|
||||
@@ -38,12 +39,12 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3
|
||||
request.FileHash = EncodedString.ToHexString(Utilities.SHA256Utility.Hash(request.FileBytes)).Value!.ToLower();
|
||||
|
||||
if (request.FileContentType is null)
|
||||
request.FileContentType = Utilities.FileNameToContentTypeMapper.GetContentTypeForImage(request.FileName!) ?? "image/png";
|
||||
request.FileContentType = MimeTypes.GetMimeMapping(request.FileName!);
|
||||
|
||||
IFlurlRequest flurlReq = client
|
||||
.CreateFlurlRequest(request, HttpMethod.Post, "marketing", "favor", "media", "image-upload");
|
||||
|
||||
using var httpContent = Utilities.FileHttpContentBuilder.Build(fileName: request.FileName, fileBytes: request.FileBytes, fileContentType: request.FileContentType, fileMetaJson: client.JsonSerializer.Serialize(request));
|
||||
using var httpContent = Utilities.HttpContentBuilder.BuildWithFile(fileName: request.FileName, fileBytes: request.FileBytes, fileContentType: request.FileContentType, fileMetaJson: client.JsonSerializer.Serialize(request));
|
||||
return await client.SendFlurlRequestAsync<Models.UploadMarketingMediaImageResponse>(flurlReq, httpContent: httpContent, cancellationToken: cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
|
@@ -6,6 +6,7 @@ using Flurl.Http;
|
||||
|
||||
namespace SKIT.FlurlHttpClient.Wechat.TenpayV3
|
||||
{
|
||||
using SKIT.FlurlHttpClient;
|
||||
using SKIT.FlurlHttpClient.Primitives;
|
||||
|
||||
public static class WechatTenpayClientExecuteMarketingShoppingReceiptExtensions
|
||||
@@ -33,12 +34,12 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3
|
||||
request.FileHash = EncodedString.ToHexString(Utilities.SHA256Utility.Hash(request.FileBytes)).Value!.ToLower();
|
||||
|
||||
if (request.FileContentType is null)
|
||||
request.FileContentType = Utilities.FileNameToContentTypeMapper.GetContentTypeForImage(request.FileName!) ?? "image/png";
|
||||
request.FileContentType = MimeTypes.GetMimeMapping(request.FileName!);
|
||||
|
||||
IFlurlRequest flurlReq = client
|
||||
.CreateFlurlRequest(request, HttpMethod.Post, "marketing", "shopping-receipt", "shoppingreceipts");
|
||||
|
||||
using var httpContent = Utilities.FileHttpContentBuilder.Build(fileName: request.FileName, fileBytes: request.FileBytes, fileContentType: request.FileContentType, fileMetaJson: client.JsonSerializer.Serialize(request));
|
||||
using var httpContent = Utilities.HttpContentBuilder.BuildWithFile(fileName: request.FileName, fileBytes: request.FileBytes, fileContentType: request.FileContentType, fileMetaJson: client.JsonSerializer.Serialize(request));
|
||||
return await client.SendFlurlRequestAsync<Models.UploadMarketingShoppingReceiptResponse>(flurlReq, httpContent: httpContent, cancellationToken: cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
|
@@ -6,6 +6,7 @@ using Flurl.Http;
|
||||
|
||||
namespace SKIT.FlurlHttpClient.Wechat.TenpayV3
|
||||
{
|
||||
using SKIT.FlurlHttpClient;
|
||||
using SKIT.FlurlHttpClient.Primitives;
|
||||
|
||||
public static class WechatTenpayClientExecuteMerchantMediaExtensions
|
||||
@@ -35,12 +36,12 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3
|
||||
request.FileHash = EncodedString.ToHexString(Utilities.SHA256Utility.Hash(request.FileBytes)).Value!.ToLower();
|
||||
|
||||
if (request.FileContentType is null)
|
||||
request.FileContentType = Utilities.FileNameToContentTypeMapper.GetContentTypeForImage(request.FileName!) ?? "image/png";
|
||||
request.FileContentType = MimeTypes.GetMimeMapping(request.FileName!);
|
||||
|
||||
IFlurlRequest flurlReq = client
|
||||
.CreateFlurlRequest(request, HttpMethod.Post, "merchant", "media", "upload");
|
||||
|
||||
using var httpContent = Utilities.FileHttpContentBuilder.Build(fileName: request.FileName, fileBytes: request.FileBytes, fileContentType: request.FileContentType, fileMetaJson: client.JsonSerializer.Serialize(request));
|
||||
using var httpContent = Utilities.HttpContentBuilder.BuildWithFile(fileName: request.FileName, fileBytes: request.FileBytes, fileContentType: request.FileContentType, fileMetaJson: client.JsonSerializer.Serialize(request));
|
||||
return await client.SendFlurlRequestAsync<Models.UploadMerchantMediaImageResponse>(flurlReq, httpContent: httpContent, cancellationToken: cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
@@ -67,12 +68,12 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3
|
||||
request.FileHash = EncodedString.ToHexString(Utilities.SHA256Utility.Hash(request.FileBytes)).Value!.ToLower();
|
||||
|
||||
if (request.FileContentType is null)
|
||||
request.FileContentType = Utilities.FileNameToContentTypeMapper.GetContentTypeForVideo(request.FileName!) ?? "video/mp4";
|
||||
request.FileContentType = MimeTypes.GetMimeMapping(request.FileName!);
|
||||
|
||||
IFlurlRequest flurlReq = client
|
||||
.CreateFlurlRequest(request, HttpMethod.Post, "merchant", "media", "video_upload");
|
||||
|
||||
using var httpContent = Utilities.FileHttpContentBuilder.Build(fileName: request.FileName, fileBytes: request.FileBytes, fileContentType: request.FileContentType, fileMetaJson: client.JsonSerializer.Serialize(request));
|
||||
using var httpContent = Utilities.HttpContentBuilder.BuildWithFile(fileName: request.FileName, fileBytes: request.FileBytes, fileContentType: request.FileContentType, fileMetaJson: client.JsonSerializer.Serialize(request));
|
||||
return await client.SendFlurlRequestAsync<Models.UploadMerchantMediaVideoResponse>(flurlReq, httpContent: httpContent, cancellationToken: cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
|
@@ -7,6 +7,7 @@ using Flurl.Http;
|
||||
|
||||
namespace SKIT.FlurlHttpClient.Wechat.TenpayV3
|
||||
{
|
||||
using SKIT.FlurlHttpClient;
|
||||
using SKIT.FlurlHttpClient.Primitives;
|
||||
|
||||
public static class WechatTenpayClientExecuteMerchantServiceExtensions
|
||||
@@ -288,12 +289,12 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3
|
||||
request.FileHash = EncodedString.ToHexString(Utilities.SHA256Utility.Hash(request.FileBytes)).Value!.ToLower();
|
||||
|
||||
if (request.FileContentType is null)
|
||||
request.FileContentType = Utilities.FileNameToContentTypeMapper.GetContentTypeForImage(request.FileName!) ?? "image/png";
|
||||
request.FileContentType = MimeTypes.GetMimeMapping(request.FileName!);
|
||||
|
||||
IFlurlRequest flurlReq = client
|
||||
.CreateFlurlRequest(request, HttpMethod.Post, "merchant-service", "images", "upload");
|
||||
|
||||
using var httpContent = Utilities.FileHttpContentBuilder.Build(fileName: request.FileName, fileBytes: request.FileBytes, fileContentType: request.FileContentType, fileMetaJson: client.JsonSerializer.Serialize(request));
|
||||
using var httpContent = Utilities.HttpContentBuilder.BuildWithFile(fileName: request.FileName, fileBytes: request.FileBytes, fileContentType: request.FileContentType, fileMetaJson: client.JsonSerializer.Serialize(request));
|
||||
return await client.SendFlurlRequestAsync<Models.UploadMerchantServiceImageResponse>(flurlReq, httpContent: httpContent, cancellationToken: cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
|
@@ -397,7 +397,7 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3
|
||||
IFlurlRequest flurlReq = client
|
||||
.CreateFlurlRequest(request, HttpMethod.Post, "new-tax-control-fapiao", "fapiao-applications", "upload-fapiao-file");
|
||||
|
||||
using var httpContent = Utilities.FileHttpContentBuilder.Build(fileName: "file.pdf", fileBytes: request.FileBytes, fileContentType: "application/pdf", fileMetaJson: client.JsonSerializer.Serialize(request));
|
||||
using var httpContent = Utilities.HttpContentBuilder.BuildWithFile(fileName: "file.pdf", fileBytes: request.FileBytes, fileContentType: "application/pdf", fileMetaJson: client.JsonSerializer.Serialize(request));
|
||||
return await client.SendFlurlRequestAsync<Models.UploadNewTaxControlFapiaoApplicationFapiaoFileResponse>(flurlReq, httpContent: httpContent, cancellationToken: cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
|
@@ -222,7 +222,7 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3
|
||||
IFlurlRequest flurlReq = client
|
||||
.CreateFlurlRequest(request, HttpMethod.Post, "taxi-invoice", "cards", "upload-file");
|
||||
|
||||
using var httpContent = Utilities.FileHttpContentBuilder.Build(fileName: "file.pdf", fileBytes: request.FileBytes, fileContentType: "application/pdf", fileMetaJson: client.JsonSerializer.Serialize(request));
|
||||
using var httpContent = Utilities.HttpContentBuilder.BuildWithFile(fileName: "file.pdf", fileBytes: request.FileBytes, fileContentType: "application/pdf", fileMetaJson: client.JsonSerializer.Serialize(request));
|
||||
return await client.SendFlurlRequestAsync<Models.UploadTaxiInvoiceCardFileResponse>(flurlReq, httpContent: httpContent, cancellationToken: cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
|
@@ -18,19 +18,5 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Models
|
||||
[Newtonsoft.Json.JsonProperty("user_label")]
|
||||
[System.Text.Json.Serialization.JsonPropertyName("user_label")]
|
||||
public string? UserLabel { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 获取或设置用户分层。
|
||||
/// </summary>
|
||||
[Newtonsoft.Json.JsonProperty("user_risk_level")]
|
||||
[System.Text.Json.Serialization.JsonPropertyName("user_risk_level")]
|
||||
public int? UserRiskLevel { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 获取或设置分层版本。
|
||||
/// </summary>
|
||||
[Newtonsoft.Json.JsonProperty("risk_level_version")]
|
||||
[System.Text.Json.Serialization.JsonPropertyName("risk_level_version")]
|
||||
public int? RiskLevelVersion { get; set; }
|
||||
}
|
||||
}
|
||||
|
@@ -1,7 +1,7 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFrameworks>net462; net471; netstandard2.0; net6.0</TargetFrameworks>
|
||||
<TargetFrameworks>net462; netstandard2.0; net6.0</TargetFrameworks>
|
||||
<LangVersion>10.0</LangVersion>
|
||||
<Nullable>enable</Nullable>
|
||||
<NullableReferenceTypes>true</NullableReferenceTypes>
|
||||
@@ -35,14 +35,10 @@
|
||||
<None Include="README.md" Pack="true" PackagePath="/" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Reference Include="System.Web" Condition="'$(TargetFramework)' == 'net462' Or '$(TargetFramework)' == 'net471'" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="BouncyCastle.Cryptography" Version="2.4.0" />
|
||||
<PackageReference Include="System.ValueTuple" Version="4.5.0" Condition="'$(TargetFramework)' == 'net462'" />
|
||||
<PackageReference Include="SKIT.FlurlHttpClient.Common" Version="3.0.0" />
|
||||
<PackageReference Include="SKIT.FlurlHttpClient.Common" Version="3.1.0" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
@@ -1,54 +0,0 @@
|
||||
using System.IO;
|
||||
|
||||
namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Utilities
|
||||
{
|
||||
internal static class FileNameToContentTypeMapper
|
||||
{
|
||||
public static string? GetContentTypeForImage(string fileName)
|
||||
{
|
||||
string extension = Path.GetExtension(fileName ?? "/")?.ToLower() ?? string.Empty;
|
||||
switch (extension)
|
||||
{
|
||||
case ".jpg":
|
||||
case ".jpeg":
|
||||
return "image/jpeg";
|
||||
case ".bmp":
|
||||
return "image/bmp";
|
||||
case ".png":
|
||||
return "image/png";
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static string? GetContentTypeForVideo(string fileName)
|
||||
{
|
||||
string extension = Path.GetExtension(fileName ?? "/")?.ToLower() ?? string.Empty;
|
||||
switch (extension)
|
||||
{
|
||||
case ".avi":
|
||||
return "video/x-msvideo";
|
||||
case ".wmv":
|
||||
return "video/x-ms-wmv";
|
||||
case ".mpeg":
|
||||
return "video/mpeg";
|
||||
case ".mov":
|
||||
return "video/quicktime";
|
||||
case ".mkv":
|
||||
return "video/mkv";
|
||||
case ".m4v":
|
||||
return "video/x-m4v";
|
||||
case ".flv":
|
||||
return "video/x-flv";
|
||||
case ".f4v":
|
||||
return "video/x-f4v";
|
||||
case ".rmvb":
|
||||
return "video/vnd.rn-realvideo";
|
||||
case ".mp4":
|
||||
return "video/mp4";
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,42 +1,35 @@
|
||||
using System;
|
||||
using System.Net.Http;
|
||||
using System.Net.Http.Headers;
|
||||
using System.Text;
|
||||
using System.Web;
|
||||
|
||||
namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Utilities
|
||||
{
|
||||
using SKIT.FlurlHttpClient;
|
||||
using SKIT.FlurlHttpClient.Wechat.TenpayV3.Constants;
|
||||
|
||||
internal static class FileHttpContentBuilder
|
||||
internal static class HttpContentBuilder
|
||||
{
|
||||
public static MultipartFormDataContent Build(string fileName, byte[] fileBytes, string fileContentType, string fileMetaJson, string formDataName = "file")
|
||||
{
|
||||
return Build(fileName: fileName, fileBytes: fileBytes, fileContentType: fileContentType, fileMetaJson: fileMetaJson, formDataName: formDataName, (_) => { }, (_) => { });
|
||||
}
|
||||
|
||||
public static MultipartFormDataContent Build(string fileName, byte[] fileBytes, string fileContentType, string fileMetaJson, string formDataName, Action<HttpContent> configureMetaHttpContent, Action<HttpContent> configureFileHttpContent)
|
||||
public static MultipartFormDataContent BuildWithFile(string fileName, byte[] fileBytes, string? fileContentType, string fileMetaJson, string formDataName = "file", Action<HttpContent>? configureMetaHttpContent = null, Action<HttpContent>? configureFileHttpContent = null)
|
||||
{
|
||||
if (fileName is null) throw new ArgumentNullException(nameof(fileName));
|
||||
if (fileMetaJson is null) throw new ArgumentNullException(nameof(fileMetaJson));
|
||||
if (formDataName is null) throw new ArgumentNullException(nameof(formDataName));
|
||||
if (configureFileHttpContent is null) throw new ArgumentNullException(nameof(configureFileHttpContent));
|
||||
|
||||
fileBytes = fileBytes ?? Array.Empty<byte>();
|
||||
fileContentType = string.IsNullOrEmpty(fileContentType) ? "application/octet-stream" : fileContentType;
|
||||
fileContentType = string.IsNullOrEmpty(fileContentType) ? MimeTypes.Binary : fileContentType;
|
||||
formDataName = formDataName.Replace("\"", string.Empty);
|
||||
|
||||
ByteArrayContent metaContent = new ByteArrayContent(Encoding.UTF8.GetBytes(fileMetaJson));
|
||||
metaContent.Headers.ContentType = MediaTypeHeaderValue.Parse("application/json");
|
||||
configureMetaHttpContent(metaContent);
|
||||
StringContent metaContent = new StringContent(fileMetaJson, null, MimeTypes.Json);
|
||||
configureMetaHttpContent?.Invoke(metaContent);
|
||||
|
||||
ByteArrayContent fileContent = new ByteArrayContent(fileBytes);
|
||||
fileContent.Headers.ContentType = MediaTypeHeaderValue.Parse(fileContentType);
|
||||
configureFileHttpContent(fileContent);
|
||||
configureFileHttpContent?.Invoke(fileContent);
|
||||
|
||||
string boundary = "--BOUNDARY--" + DateTimeOffset.Now.Ticks.ToString("x");
|
||||
MultipartFormDataContent httpContent = new MultipartFormDataContent(boundary);
|
||||
httpContent.Headers.ContentType = MediaTypeHeaderValue.Parse($"multipart/form-data; boundary={boundary}");
|
||||
httpContent.Headers.ContentType = MediaTypeHeaderValue.Parse($"{MimeTypes.FormData}; boundary={boundary}");
|
||||
httpContent.Add(metaContent, $"\"{FormDataFields.FORMDATA_META}\"");
|
||||
httpContent.Add(fileContent, $"\"{formDataName}\"", $"\"{HttpUtility.UrlEncode(fileName)}\"");
|
||||
return httpContent;
|
@@ -3,6 +3,7 @@ using System.Xml.Linq;
|
||||
|
||||
namespace SKIT.FlurlHttpClient.Wechat.Work
|
||||
{
|
||||
using SKIT.FlurlHttpClient.Internal;
|
||||
using SKIT.FlurlHttpClient.Primitives;
|
||||
|
||||
/// <summary>
|
||||
@@ -130,7 +131,7 @@ namespace SKIT.FlurlHttpClient.Wechat.Work
|
||||
|
||||
try
|
||||
{
|
||||
xml = Utilities.XmlHelper.Serialize(webhookEvent);
|
||||
xml = _XmlSimpleSerializer.Serialize(webhookEvent, typeof(TEvent));
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@@ -363,7 +364,7 @@ namespace SKIT.FlurlHttpClient.Wechat.Work
|
||||
throw new WechatWorkException("Failed to decrypt event data, because the encrypted data is empty.");
|
||||
|
||||
webhookXml = Utilities.WxMsgCryptor.AESDecrypt(cipherText: encryptedXml!, encodingAESKey: client.Credentials.PushEncodingAESKey!, out _);
|
||||
return Utilities.XmlHelper.Deserialize<TEvent>(webhookXml);
|
||||
return (TEvent)_XmlSimpleSerializer.Deserialize(webhookXml, typeof(TEvent));
|
||||
}
|
||||
catch (WechatWorkException)
|
||||
{
|
||||
|
@@ -45,23 +45,14 @@ namespace SKIT.FlurlHttpClient.Wechat.Work
|
||||
}
|
||||
|
||||
if (request.FileContentType is null)
|
||||
{
|
||||
if (TYPE_IMAGE.Equals(request.Type))
|
||||
request.FileContentType = Utilities.FileNameToContentTypeMapper.GetContentTypeForImage(request.FileName!) ?? "image/png";
|
||||
else if (TYPE_VOICE.Equals(request.Type))
|
||||
request.FileContentType = Utilities.FileNameToContentTypeMapper.GetContentTypeForVoice(request.FileName!) ?? "audio/mp3";
|
||||
else if (TYPE_VIDEO.Equals(request.Type))
|
||||
request.FileContentType = Utilities.FileNameToContentTypeMapper.GetContentTypeForVideo(request.FileName!) ?? "video/mp4";
|
||||
else
|
||||
request.FileContentType = "application/octet-stream";
|
||||
}
|
||||
request.FileContentType = MimeTypes.GetMimeMapping(request.FileName!);
|
||||
|
||||
IFlurlRequest flurlReq = client
|
||||
.CreateFlurlRequest(request, HttpMethod.Post, "cgi-bin", "media", "upload")
|
||||
.SetQueryParam("access_token", request.AccessToken)
|
||||
.SetQueryParam("type", request.Type);
|
||||
|
||||
using var httpContent = Utilities.FileHttpContentBuilder.Build(fileName: request.FileName, fileBytes: request.FileBytes, fileContentType: request.FileContentType, formDataName: "media");
|
||||
using var httpContent = Utilities.HttpContentBuilder.BuildWithFile(fileName: request.FileName, fileBytes: request.FileBytes, fileContentType: request.FileContentType, formDataName: "media");
|
||||
return await client.SendFlurlRequestAsync<Models.CgibinMediaUploadResponse>(flurlReq, httpContent: httpContent, cancellationToken: cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
@@ -87,13 +78,13 @@ namespace SKIT.FlurlHttpClient.Wechat.Work
|
||||
request.FileName = Guid.NewGuid().ToString("N").ToLower() + ".png";
|
||||
|
||||
if (request.FileContentType is null)
|
||||
request.FileContentType = Utilities.FileNameToContentTypeMapper.GetContentTypeForImage(request.FileName!) ?? "image/png";
|
||||
request.FileContentType = MimeTypes.GetMimeMapping(request.FileName!);
|
||||
|
||||
IFlurlRequest flurlReq = client
|
||||
.CreateFlurlRequest(request, HttpMethod.Post, "cgi-bin", "media", "uploadimg")
|
||||
.SetQueryParam("access_token", request.AccessToken);
|
||||
|
||||
using var httpContent = Utilities.FileHttpContentBuilder.Build(fileName: request.FileName, fileBytes: request.FileBytes, fileContentType: request.FileContentType, formDataName: "media");
|
||||
using var httpContent = Utilities.HttpContentBuilder.BuildWithFile(fileName: request.FileName, fileBytes: request.FileBytes, fileContentType: request.FileContentType, formDataName: "media");
|
||||
return await client.SendFlurlRequestAsync<Models.CgibinMediaUploadImageResponse>(flurlReq, httpContent: httpContent, cancellationToken: cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
@@ -132,16 +123,7 @@ namespace SKIT.FlurlHttpClient.Wechat.Work
|
||||
}
|
||||
|
||||
if (request.FileContentType is null)
|
||||
{
|
||||
if (TYPE_IMAGE.Equals(request.Type))
|
||||
request.FileContentType = Utilities.FileNameToContentTypeMapper.GetContentTypeForImage(request.FileName!) ?? "image/png";
|
||||
else if (TYPE_VIDEO.Equals(request.Type))
|
||||
request.FileContentType = Utilities.FileNameToContentTypeMapper.GetContentTypeForVideo(request.FileName!) ?? "video/mp4";
|
||||
else if (TYPE_FILE.Equals(request.Type))
|
||||
request.FileContentType = Utilities.FileNameToContentTypeMapper.GetContentTypeForVoice(request.FileName!) ?? "text/plain";
|
||||
else
|
||||
request.FileContentType = "application/octet-stream";
|
||||
}
|
||||
request.FileContentType = MimeTypes.GetMimeMapping(request.FileName!);
|
||||
|
||||
IFlurlRequest flurlReq = client
|
||||
.CreateFlurlRequest(request, HttpMethod.Post, "cgi-bin", "media", "upload_attachment")
|
||||
@@ -149,7 +131,7 @@ namespace SKIT.FlurlHttpClient.Wechat.Work
|
||||
.SetQueryParam("media_type", request.Type)
|
||||
.SetQueryParam("attachment_type", request.AttachmentType);
|
||||
|
||||
using var httpContent = Utilities.FileHttpContentBuilder.Build(fileName: request.FileName, fileBytes: request.FileBytes, fileContentType: request.FileContentType, formDataName: "media");
|
||||
using var httpContent = Utilities.HttpContentBuilder.BuildWithFile(fileName: request.FileName, fileBytes: request.FileBytes, fileContentType: request.FileContentType, formDataName: "media");
|
||||
return await client.SendFlurlRequestAsync<Models.CgibinMediaUploadAttachmentResponse>(flurlReq, httpContent: httpContent, cancellationToken: cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
|
@@ -29,13 +29,13 @@ namespace SKIT.FlurlHttpClient.Wechat.Work
|
||||
request.FileName = Guid.NewGuid().ToString("N").ToLower() + ".png";
|
||||
|
||||
if (request.FileContentType is null)
|
||||
request.FileContentType = Utilities.FileNameToContentTypeMapper.GetContentTypeForImage(request.FileName!) ?? "image/png";
|
||||
request.FileContentType = MimeTypes.GetMimeMapping(request.FileName!);
|
||||
|
||||
IFlurlRequest flurlReq = client
|
||||
.CreateFlurlRequest(request, HttpMethod.Post, "cgi-bin", "miniapppay", "upload_image")
|
||||
.SetQueryParam("access_token", request.AccessToken);
|
||||
|
||||
using var httpContent = Utilities.FileHttpContentBuilder.Build(fileName: request.FileName, fileBytes: request.FileBytes, fileContentType: request.FileContentType, formDataName: "media");
|
||||
using var httpContent = Utilities.HttpContentBuilder.BuildWithFile(fileName: request.FileName, fileBytes: request.FileBytes, fileContentType: request.FileContentType, formDataName: "media");
|
||||
return await client.SendFlurlRequestAsync<Models.CgibinMiniAppPayUploadImageResponse>(flurlReq, httpContent: httpContent, cancellationToken: cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
|
@@ -341,23 +341,14 @@ namespace SKIT.FlurlHttpClient.Wechat.Work
|
||||
}
|
||||
|
||||
if (request.FileContentType is null)
|
||||
{
|
||||
if (TYPE_IMAGE.Equals(request.Type))
|
||||
request.FileContentType = Utilities.FileNameToContentTypeMapper.GetContentTypeForImage(request.FileName!) ?? "image/png";
|
||||
else if (TYPE_VOICE.Equals(request.Type))
|
||||
request.FileContentType = Utilities.FileNameToContentTypeMapper.GetContentTypeForVoice(request.FileName!) ?? "audio/mp3";
|
||||
else if (TYPE_VIDEO.Equals(request.Type))
|
||||
request.FileContentType = Utilities.FileNameToContentTypeMapper.GetContentTypeForVideo(request.FileName!) ?? "video/mp4";
|
||||
else
|
||||
request.FileContentType = "application/octet-stream";
|
||||
}
|
||||
request.FileContentType = MimeTypes.GetMimeMapping(request.FileName!);
|
||||
|
||||
IFlurlRequest flurlReq = client
|
||||
.CreateFlurlRequest(request, HttpMethod.Post, "cgi-bin", "service", "media", "upload")
|
||||
.SetQueryParam("provider_access_token", request.ProviderAccessToken)
|
||||
.SetQueryParam("type", request.Type);
|
||||
|
||||
using var httpContent = Utilities.FileHttpContentBuilder.Build(fileName: request.FileName, fileBytes: request.FileBytes, fileContentType: request.FileContentType, formDataName: "media");
|
||||
using var httpContent = Utilities.HttpContentBuilder.BuildWithFile(fileName: request.FileName, fileBytes: request.FileBytes, fileContentType: request.FileContentType, formDataName: "media");
|
||||
return await client.SendFlurlRequestAsync<Models.CgibinServiceMediaUploadResponse>(flurlReq, httpContent: httpContent, cancellationToken: cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
#endregion
|
||||
|
@@ -1,7 +1,7 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFrameworks>net462; net471; netstandard2.0; net6.0</TargetFrameworks>
|
||||
<TargetFrameworks>net462; netstandard2.0; net6.0</TargetFrameworks>
|
||||
<LangVersion>10.0</LangVersion>
|
||||
<Nullable>enable</Nullable>
|
||||
<NullableReferenceTypes>true</NullableReferenceTypes>
|
||||
@@ -42,13 +42,9 @@
|
||||
</ContentWithTargetPath>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Reference Include="System.Web" Condition="'$(TargetFramework)' == 'net462' Or '$(TargetFramework)' == 'net471'" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="BouncyCastle.Cryptography" Version="2.4.0" />
|
||||
<PackageReference Include="SKIT.FlurlHttpClient.Common" Version="3.0.0" />
|
||||
<PackageReference Include="SKIT.FlurlHttpClient.Common" Version="3.1.0" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
@@ -1,50 +0,0 @@
|
||||
using System.IO;
|
||||
|
||||
namespace SKIT.FlurlHttpClient.Wechat.Work.Utilities
|
||||
{
|
||||
internal static class FileNameToContentTypeMapper
|
||||
{
|
||||
public static string? GetContentTypeForImage(string fileName)
|
||||
{
|
||||
string extension = Path.GetExtension(fileName ?? "/")?.ToLower() ?? string.Empty;
|
||||
switch (extension)
|
||||
{
|
||||
case ".jpg":
|
||||
case ".jpeg":
|
||||
return "image/jpeg";
|
||||
case ".gif":
|
||||
return "image/gif";
|
||||
case ".png":
|
||||
return "image/bmp";
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static string? GetContentTypeForVoice(string fileName)
|
||||
{
|
||||
string extension = Path.GetExtension(fileName ?? "/")?.ToLower() ?? string.Empty;
|
||||
switch (extension)
|
||||
{
|
||||
case ".mp3":
|
||||
return "audio/mpeg";
|
||||
case ".amr":
|
||||
return "audio/amr";
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static string? GetContentTypeForVideo(string fileName)
|
||||
{
|
||||
string extension = Path.GetExtension(fileName ?? "/")?.ToLower() ?? string.Empty;
|
||||
switch (extension)
|
||||
{
|
||||
case ".mp4":
|
||||
return "video/mp4";
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
@@ -5,22 +5,18 @@ using System.Text;
|
||||
|
||||
namespace SKIT.FlurlHttpClient.Wechat.Work.Utilities
|
||||
{
|
||||
internal static class FileHttpContentBuilder
|
||||
{
|
||||
public static MultipartFormDataContent Build(string fileName, byte[] fileBytes, string fileContentType, string formDataName)
|
||||
{
|
||||
return Build(fileName: fileName, fileBytes: fileBytes, fileContentType: fileContentType, formDataName: formDataName, (_) => { });
|
||||
}
|
||||
using SKIT.FlurlHttpClient;
|
||||
|
||||
public static MultipartFormDataContent Build(string fileName, byte[] fileBytes, string fileContentType, string formDataName, Action<HttpContent> configureFileHttpContent)
|
||||
internal static class HttpContentBuilder
|
||||
{
|
||||
public static MultipartFormDataContent BuildWithFile(string fileName, byte[] fileBytes, string? fileContentType, string formDataName, Action<HttpContent>? configureFileHttpContent = null)
|
||||
{
|
||||
if (fileName is null) throw new ArgumentNullException(nameof(fileName));
|
||||
if (formDataName is null) throw new ArgumentNullException(nameof(formDataName));
|
||||
if (configureFileHttpContent is null) throw new ArgumentNullException(nameof(configureFileHttpContent));
|
||||
|
||||
fileName = fileName.Replace("\"", string.Empty);
|
||||
fileBytes = fileBytes ?? Array.Empty<byte>();
|
||||
fileContentType = string.IsNullOrEmpty(fileContentType) ? "application/octet-stream" : fileContentType;
|
||||
fileContentType = string.IsNullOrEmpty(fileContentType) ? MimeTypes.Binary : fileContentType;
|
||||
formDataName = formDataName.Replace("\"", string.Empty);
|
||||
|
||||
// HACKED: 默认不支持 Unicode 文件名 https://github.com/dotnet/runtime/issues/22996
|
||||
@@ -33,11 +29,11 @@ namespace SKIT.FlurlHttpClient.Wechat.Work.Utilities
|
||||
fileContent.Headers.ContentDisposition = ContentDispositionHeaderValue.Parse($"form-data; name=\"{formDataName}\"; filename=\"{hackedFileName}\"");
|
||||
fileContent.Headers.ContentType = MediaTypeHeaderValue.Parse(fileContentType);
|
||||
fileContent.Headers.ContentLength = fileBytes.Length;
|
||||
configureFileHttpContent(fileContent);
|
||||
configureFileHttpContent?.Invoke(fileContent);
|
||||
|
||||
string boundary = "--BOUNDARY--" + DateTimeOffset.Now.Ticks.ToString("x");
|
||||
MultipartFormDataContent httpContent = new MultipartFormDataContent(boundary);
|
||||
httpContent.Headers.ContentType = MediaTypeHeaderValue.Parse($"multipart/form-data; boundary={boundary}");
|
||||
httpContent.Headers.ContentType = MediaTypeHeaderValue.Parse($"{MimeTypes.FormData}; boundary={boundary}");
|
||||
httpContent.Add(fileContent);
|
||||
return httpContent;
|
||||
}
|
@@ -1,31 +0,0 @@
|
||||
using System;
|
||||
|
||||
namespace SKIT.FlurlHttpClient.Wechat.Work.Utilities
|
||||
{
|
||||
using SKIT.FlurlHttpClient.Internal;
|
||||
|
||||
internal static class XmlHelper
|
||||
{
|
||||
public static string Serialize(object obj, Type type)
|
||||
{
|
||||
return _XmlSimpleSerializer.Serialize(obj, type);
|
||||
}
|
||||
|
||||
public static string Serialize<T>(T obj)
|
||||
where T : class
|
||||
{
|
||||
return Serialize(obj, typeof(T));
|
||||
}
|
||||
|
||||
public static object Deserialize(string xml, Type type)
|
||||
{
|
||||
return _XmlSimpleSerializer.Deserialize(xml, type);
|
||||
}
|
||||
|
||||
public static T Deserialize<T>(string xml)
|
||||
where T : class
|
||||
{
|
||||
return (T)Deserialize(xml, typeof(T));
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user