diff --git a/src/SKIT.FlurlHttpClient.Wechat.Api/Extensions/WechatApiClientExecuteCardInvoiceExtensions.cs b/src/SKIT.FlurlHttpClient.Wechat.Api/Extensions/WechatApiClientExecuteCardInvoiceExtensions.cs index 9511adb7..5570de84 100644 --- a/src/SKIT.FlurlHttpClient.Wechat.Api/Extensions/WechatApiClientExecuteCardInvoiceExtensions.cs +++ b/src/SKIT.FlurlHttpClient.Wechat.Api/Extensions/WechatApiClientExecuteCardInvoiceExtensions.cs @@ -1,6 +1,5 @@ using System; using System.Net.Http; -using System.Net.Http.Headers; using System.Threading; using System.Threading.Tasks; using Flurl; diff --git a/src/SKIT.FlurlHttpClient.Wechat.Api/Extensions/WechatApiClientExecuteCgibinComponentExtensions.cs b/src/SKIT.FlurlHttpClient.Wechat.Api/Extensions/WechatApiClientExecuteCgibinComponentExtensions.cs index 2bab3bcb..c6029e9e 100644 --- a/src/SKIT.FlurlHttpClient.Wechat.Api/Extensions/WechatApiClientExecuteCgibinComponentExtensions.cs +++ b/src/SKIT.FlurlHttpClient.Wechat.Api/Extensions/WechatApiClientExecuteCgibinComponentExtensions.cs @@ -1,9 +1,7 @@ using System; using System.Net.Http; -using System.Net.Http.Headers; using System.Threading; using System.Threading.Tasks; -using System.Web; using Flurl; using Flurl.Http; diff --git a/src/SKIT.FlurlHttpClient.Wechat.Api/Extensions/WechatApiClientExecuteCgibinMaterialExtensions.cs b/src/SKIT.FlurlHttpClient.Wechat.Api/Extensions/WechatApiClientExecuteCgibinMaterialExtensions.cs index f2c05ebb..c67a6d0d 100644 --- a/src/SKIT.FlurlHttpClient.Wechat.Api/Extensions/WechatApiClientExecuteCgibinMaterialExtensions.cs +++ b/src/SKIT.FlurlHttpClient.Wechat.Api/Extensions/WechatApiClientExecuteCgibinMaterialExtensions.cs @@ -1,10 +1,8 @@ using System; using System.Net.Http; -using System.Net.Http.Headers; using System.Text; using System.Threading; using System.Threading.Tasks; -using System.Web; using Flurl; using Flurl.Http; diff --git a/src/SKIT.FlurlHttpClient.Wechat.Api/Extensions/WechatApiClientExecuteCgibinMediaExtensions.cs b/src/SKIT.FlurlHttpClient.Wechat.Api/Extensions/WechatApiClientExecuteCgibinMediaExtensions.cs index 7b4ec00a..c7fcc2cd 100644 --- a/src/SKIT.FlurlHttpClient.Wechat.Api/Extensions/WechatApiClientExecuteCgibinMediaExtensions.cs +++ b/src/SKIT.FlurlHttpClient.Wechat.Api/Extensions/WechatApiClientExecuteCgibinMediaExtensions.cs @@ -3,7 +3,6 @@ using System.Net.Http; using System.Net.Http.Headers; using System.Threading; using System.Threading.Tasks; -using System.Web; using Flurl; using Flurl.Http; diff --git a/src/SKIT.FlurlHttpClient.Wechat.Api/Extensions/WechatApiClientExecuteCustomServiceExtensions.cs b/src/SKIT.FlurlHttpClient.Wechat.Api/Extensions/WechatApiClientExecuteCustomServiceExtensions.cs index 618a663d..f5c91317 100644 --- a/src/SKIT.FlurlHttpClient.Wechat.Api/Extensions/WechatApiClientExecuteCustomServiceExtensions.cs +++ b/src/SKIT.FlurlHttpClient.Wechat.Api/Extensions/WechatApiClientExecuteCustomServiceExtensions.cs @@ -1,6 +1,5 @@ using System; using System.Net.Http; -using System.Net.Http.Headers; using System.Threading; using System.Threading.Tasks; using Flurl; diff --git a/src/SKIT.FlurlHttpClient.Wechat.Api/Extensions/WechatApiClientExecuteShopExtensions.cs b/src/SKIT.FlurlHttpClient.Wechat.Api/Extensions/WechatApiClientExecuteShopExtensions.cs index 4d01bf94..12f9c2f7 100644 --- a/src/SKIT.FlurlHttpClient.Wechat.Api/Extensions/WechatApiClientExecuteShopExtensions.cs +++ b/src/SKIT.FlurlHttpClient.Wechat.Api/Extensions/WechatApiClientExecuteShopExtensions.cs @@ -1,6 +1,5 @@ using System; using System.Net.Http; -using System.Net.Http.Headers; using System.Threading; using System.Threading.Tasks; using Flurl; diff --git a/src/SKIT.FlurlHttpClient.Wechat.Api/Extensions/WechatApiClientExecuteWxaExtensions.cs b/src/SKIT.FlurlHttpClient.Wechat.Api/Extensions/WechatApiClientExecuteWxaExtensions.cs index d072b0f9..99b72c55 100644 --- a/src/SKIT.FlurlHttpClient.Wechat.Api/Extensions/WechatApiClientExecuteWxaExtensions.cs +++ b/src/SKIT.FlurlHttpClient.Wechat.Api/Extensions/WechatApiClientExecuteWxaExtensions.cs @@ -1,6 +1,5 @@ using System; using System.Net.Http; -using System.Net.Http.Headers; using System.Threading; using System.Threading.Tasks; using Flurl; diff --git a/src/SKIT.FlurlHttpClient.Wechat.Api/Models/Shop/ECAftersale/ShopECAftersaleAcceptReturnRequest.cs b/src/SKIT.FlurlHttpClient.Wechat.Api/Models/Shop/ECAftersale/ShopECAftersaleAcceptReturnRequest.cs index b94c92ef..0a82329c 100644 --- a/src/SKIT.FlurlHttpClient.Wechat.Api/Models/Shop/ECAftersale/ShopECAftersaleAcceptReturnRequest.cs +++ b/src/SKIT.FlurlHttpClient.Wechat.Api/Models/Shop/ECAftersale/ShopECAftersaleAcceptReturnRequest.cs @@ -8,7 +8,7 @@ public static class Types { public class Address : ShopAccountUpdateInfoRequest.Types.Address - { + { } } diff --git a/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Extensions/WechatTenpayClientExecuteMarketingBankExtensions.cs b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Extensions/WechatTenpayClientExecuteMarketingBankExtensions.cs index a80b0ea5..0712fb99 100644 --- a/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Extensions/WechatTenpayClientExecuteMarketingBankExtensions.cs +++ b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Extensions/WechatTenpayClientExecuteMarketingBankExtensions.cs @@ -1,10 +1,7 @@ using System; using System.Net.Http; -using System.Net.Http.Headers; -using System.Text; using System.Threading; using System.Threading.Tasks; -using System.Web; using Flurl.Http; namespace SKIT.FlurlHttpClient.Wechat.TenpayV3 @@ -40,17 +37,7 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3 IFlurlRequest flurlReq = client .CreateRequest(request, HttpMethod.Post, "marketing", "bank", "packages", request.PackageId, "tasks"); - string boundary = "--BOUNDARY--" + DateTimeOffset.Now.Ticks.ToString("x"); - using var fileContent = new ByteArrayContent(request.FileBytes ?? Array.Empty()); - using var metaContent = new ByteArrayContent(Encoding.UTF8.GetBytes(client.JsonSerializer.Serialize(request))); - using var httpContent = new MultipartFormDataContent(boundary); - httpContent.Add(metaContent, $"\"{Constants.FormDataFields.FORMDATA_META}\""); - httpContent.Add(fileContent, "\"file\"", $"\"{HttpUtility.UrlEncode(request.FileName)}\""); - httpContent.Headers.ContentType = MediaTypeHeaderValue.Parse("multipart/form-data; boundary=" + boundary); - metaContent.Headers.ContentType = MediaTypeHeaderValue.Parse("application/json"); - fileContent.Headers.ContentType = MediaTypeHeaderValue.Parse(request.FileContentType); - fileContent.Headers.ContentLength = request.FileBytes?.Length; - + using var httpContent = Utilities.FileHttpContentBuilder.Build(fileName: request.FileName, fileBytes: request.FileBytes, fileContentType: request.FileContentType, fileMetaJson: client.JsonSerializer.Serialize(request)); return await client.SendRequestAsync(flurlReq, httpContent: httpContent, cancellationToken: cancellationToken); } } diff --git a/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Extensions/WechatTenpayClientExecuteMarketingMediaExtensions.cs b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Extensions/WechatTenpayClientExecuteMarketingMediaExtensions.cs index aa444922..30f47182 100644 --- a/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Extensions/WechatTenpayClientExecuteMarketingMediaExtensions.cs +++ b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Extensions/WechatTenpayClientExecuteMarketingMediaExtensions.cs @@ -1,10 +1,7 @@ using System; using System.Net.Http; -using System.Net.Http.Headers; -using System.Text; using System.Threading; using System.Threading.Tasks; -using System.Web; using Flurl.Http; namespace SKIT.FlurlHttpClient.Wechat.TenpayV3 @@ -40,17 +37,7 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3 IFlurlRequest flurlReq = client .CreateRequest(request, HttpMethod.Post, "marketing", "favor", "media", "image-upload"); - string boundary = "--BOUNDARY--" + DateTimeOffset.Now.Ticks.ToString("x"); - using var fileContent = new ByteArrayContent(request.FileBytes ?? Array.Empty()); - using var metaContent = new ByteArrayContent(Encoding.UTF8.GetBytes(client.JsonSerializer.Serialize(request))); - using var httpContent = new MultipartFormDataContent(boundary); - httpContent.Add(metaContent, $"\"{Constants.FormDataFields.FORMDATA_META}\""); - httpContent.Add(fileContent, "\"file\"", $"\"{HttpUtility.UrlEncode(request.FileName)}\""); - httpContent.Headers.ContentType = MediaTypeHeaderValue.Parse("multipart/form-data; boundary=" + boundary); - metaContent.Headers.ContentType = MediaTypeHeaderValue.Parse("application/json"); - fileContent.Headers.ContentType = MediaTypeHeaderValue.Parse(request.FileContentType); - fileContent.Headers.ContentLength = request.FileBytes?.Length; - + using var httpContent = Utilities.FileHttpContentBuilder.Build(fileName: request.FileName, fileBytes: request.FileBytes, fileContentType: request.FileContentType, fileMetaJson: client.JsonSerializer.Serialize(request)); return await client.SendRequestAsync(flurlReq, httpContent: httpContent, cancellationToken: cancellationToken); } } diff --git a/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Extensions/WechatTenpayClientExecuteMerchantMediaExtensions.cs b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Extensions/WechatTenpayClientExecuteMerchantMediaExtensions.cs index e2283b03..c3d97bcc 100644 --- a/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Extensions/WechatTenpayClientExecuteMerchantMediaExtensions.cs +++ b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Extensions/WechatTenpayClientExecuteMerchantMediaExtensions.cs @@ -41,17 +41,7 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3 IFlurlRequest flurlReq = client .CreateRequest(request, HttpMethod.Post, "merchant", "media", "upload"); - string boundary = "--BOUNDARY--" + DateTimeOffset.Now.Ticks.ToString("x"); - using var fileContent = new ByteArrayContent(request.FileBytes ?? Array.Empty()); - using var metaContent = new StringContent(client.JsonSerializer.Serialize(request), Encoding.UTF8, "application/json"); - using var httpContent = new MultipartFormDataContent(boundary); - httpContent.Add(metaContent, $"\"{Constants.FormDataFields.FORMDATA_META}\""); - httpContent.Add(fileContent, "\"file\"", $"\"{HttpUtility.UrlEncode(request.FileName)}\""); - httpContent.Headers.ContentType = MediaTypeHeaderValue.Parse("multipart/form-data; boundary=" + boundary); - metaContent.Headers.ContentType = MediaTypeHeaderValue.Parse("application/json"); - fileContent.Headers.ContentType = MediaTypeHeaderValue.Parse(request.FileContentType); - fileContent.Headers.ContentLength = request.FileBytes?.Length; - + using var httpContent = Utilities.FileHttpContentBuilder.Build(fileName: request.FileName, fileBytes: request.FileBytes, fileContentType: request.FileContentType, fileMetaJson: client.JsonSerializer.Serialize(request)); return await client.SendRequestAsync(flurlReq, httpContent: httpContent, cancellationToken: cancellationToken); } @@ -81,17 +71,7 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3 IFlurlRequest flurlReq = client .CreateRequest(request, HttpMethod.Post, "merchant", "media", "video_upload"); - string boundary = "--BOUNDARY--" + DateTimeOffset.Now.Ticks.ToString("x"); - using var fileContent = new ByteArrayContent(request.FileBytes ?? Array.Empty()); - using var metaContent = new ByteArrayContent(Encoding.UTF8.GetBytes(client.JsonSerializer.Serialize(request))); - using var httpContent = new MultipartFormDataContent(boundary); - httpContent.Add(metaContent, $"\"{Constants.FormDataFields.FORMDATA_META}\""); - httpContent.Add(fileContent, "\"file\"", $"\"{HttpUtility.UrlEncode(request.FileName)}\""); - httpContent.Headers.ContentType = MediaTypeHeaderValue.Parse("multipart/form-data; boundary=" + boundary); - metaContent.Headers.ContentType = MediaTypeHeaderValue.Parse("application/json"); - fileContent.Headers.ContentType = MediaTypeHeaderValue.Parse(request.FileContentType); - fileContent.Headers.ContentLength = request.FileBytes?.Length; - + using var httpContent = Utilities.FileHttpContentBuilder.Build(fileName: request.FileName, fileBytes: request.FileBytes, fileContentType: request.FileContentType, fileMetaJson: client.JsonSerializer.Serialize(request)); return await client.SendRequestAsync(flurlReq, httpContent: httpContent, cancellationToken: cancellationToken); } } diff --git a/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Extensions/WechatTenpayClientExecuteMerchantServiceExtensions.cs b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Extensions/WechatTenpayClientExecuteMerchantServiceExtensions.cs index 5b58193b..bce79606 100644 --- a/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Extensions/WechatTenpayClientExecuteMerchantServiceExtensions.cs +++ b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Extensions/WechatTenpayClientExecuteMerchantServiceExtensions.cs @@ -1,10 +1,7 @@ using System; using System.Net.Http; -using System.Net.Http.Headers; -using System.Text; using System.Threading; using System.Threading.Tasks; -using System.Web; using Flurl; using Flurl.Http; @@ -138,6 +135,26 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3 return await client.SendRequestWithJsonAsync(flurlReq, data: request, cancellationToken: cancellationToken); } + /// + /// 异步调用 [POST] /merchant-service/complaints-v2/{complaint_id}/update-refund-progress 接口。 + /// REF: https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter10_2_19.shtml + /// REF: https://pay.weixin.qq.com/wiki/doc/apiv3_partner/apis/chapter10_2_19.shtml + /// + /// + /// + /// + /// + public static async Task ExecuteUpdateMerchantServiceComplaintRefundProgressAsync(this WechatTenpayClient client, Models.UpdateMerchantServiceComplaintRefundProgressRequest request, CancellationToken cancellationToken = default) + { + if (client is null) throw new ArgumentNullException(nameof(client)); + if (request is null) throw new ArgumentNullException(nameof(request)); + + IFlurlRequest flurlReq = client + .CreateRequest(request, HttpMethod.Post, "merchant-service", "complaints-v2", request.ComplaintId, "update-refund-progress"); + + return await client.SendRequestWithJsonAsync(flurlReq, data: request, cancellationToken: cancellationToken); + } + /// /// 异步调用 [POST] /merchant-service/complaint-notifications 接口。 /// REF: https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter10_2_2.shtml @@ -244,17 +261,7 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3 IFlurlRequest flurlReq = client .CreateRequest(request, HttpMethod.Post, "merchant-service", "images", "upload"); - string boundary = "--BOUNDARY--" + DateTimeOffset.Now.Ticks.ToString("x"); - using var fileContent = new ByteArrayContent(request.FileBytes ?? Array.Empty()); - using var metaContent = new ByteArrayContent(Encoding.UTF8.GetBytes(client.JsonSerializer.Serialize(request))); - using var httpContent = new MultipartFormDataContent(boundary); - httpContent.Add(metaContent, $"\"{Constants.FormDataFields.FORMDATA_META}\""); - httpContent.Add(fileContent, "\"file\"", $"\"{HttpUtility.UrlEncode(request.FileName)}\""); - httpContent.Headers.ContentType = MediaTypeHeaderValue.Parse("multipart/form-data; boundary=" + boundary); - metaContent.Headers.ContentType = MediaTypeHeaderValue.Parse("application/json"); - fileContent.Headers.ContentType = MediaTypeHeaderValue.Parse(request.FileContentType); - fileContent.Headers.ContentLength = request.FileBytes?.Length; - + using var httpContent = Utilities.FileHttpContentBuilder.Build(fileName: request.FileName, fileBytes: request.FileBytes, fileContentType: request.FileContentType, fileMetaJson: client.JsonSerializer.Serialize(request)); return await client.SendRequestAsync(flurlReq, httpContent: httpContent, cancellationToken: cancellationToken); } diff --git a/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/HKTransactions/CreateHKTransactionJsapiRequest.cs b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/HKTransactions/CreateHKTransactionJsapiRequest.cs index ead38bfb..1f9581d7 100644 --- a/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/HKTransactions/CreateHKTransactionJsapiRequest.cs +++ b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/HKTransactions/CreateHKTransactionJsapiRequest.cs @@ -19,7 +19,7 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Models public class Detail : CreateHKTransactionAppRequest.Types.Detail { - public new static class Types + public static new class Types { public class GoodsDetail : CreateHKTransactionAppRequest.Types.Detail.Types.GoodsDetail { @@ -29,7 +29,7 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Models public class Scene : CreateHKTransactionAppRequest.Types.Scene { - public new static class Types + public static new class Types { public class Store : CreateHKTransactionAppRequest.Types.Scene.Types.Store { diff --git a/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/HKTransactions/CreateHKTransactionMWebRequest.cs b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/HKTransactions/CreateHKTransactionMWebRequest.cs index 97c0c484..d78f000c 100644 --- a/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/HKTransactions/CreateHKTransactionMWebRequest.cs +++ b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/HKTransactions/CreateHKTransactionMWebRequest.cs @@ -19,7 +19,7 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Models public class Detail : CreateHKTransactionAppRequest.Types.Detail { - public new static class Types + public static new class Types { public class GoodsDetail : CreateHKTransactionAppRequest.Types.Detail.Types.GoodsDetail { @@ -29,7 +29,7 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Models public class Scene : CreateHKTransactionAppRequest.Types.Scene { - public new static class Types + public static new class Types { public class Store : CreateHKTransactionAppRequest.Types.Scene.Types.Store { diff --git a/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/HKTransactions/CreateHKTransactionMicroPayRequest.cs b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/HKTransactions/CreateHKTransactionMicroPayRequest.cs index 46084b4d..657779ee 100644 --- a/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/HKTransactions/CreateHKTransactionMicroPayRequest.cs +++ b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/HKTransactions/CreateHKTransactionMicroPayRequest.cs @@ -23,7 +23,7 @@ public class Detail : CreateHKTransactionAppRequest.Types.Detail { - public new static class Types + public static new class Types { public class GoodsDetail : CreateHKTransactionAppRequest.Types.Detail.Types.GoodsDetail { @@ -33,7 +33,7 @@ public class Scene : CreateHKTransactionAppRequest.Types.Scene { - public new static class Types + public static new class Types { public class Store : CreateHKTransactionAppRequest.Types.Scene.Types.Store { diff --git a/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/HKTransactions/CreateHKTransactionNativeRequest.cs b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/HKTransactions/CreateHKTransactionNativeRequest.cs index 5a862bcb..b5b6a523 100644 --- a/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/HKTransactions/CreateHKTransactionNativeRequest.cs +++ b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/HKTransactions/CreateHKTransactionNativeRequest.cs @@ -19,7 +19,7 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Models public class Detail : CreateHKTransactionAppRequest.Types.Detail { - public new static class Types + public static new class Types { public class GoodsDetail : CreateHKTransactionAppRequest.Types.Detail.Types.GoodsDetail { @@ -29,7 +29,7 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Models public class Scene : CreateHKTransactionAppRequest.Types.Scene { - public new static class Types + public static new class Types { public class Store : CreateHKTransactionAppRequest.Types.Scene.Types.Store { diff --git a/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Properties/AssemblyInfo.cs b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Properties/AssemblyInfo.cs index ae4629e6..453ec1b1 100644 --- a/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Properties/AssemblyInfo.cs +++ b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Properties/AssemblyInfo.cs @@ -1,3 +1,3 @@ using System.Runtime.CompilerServices; -[assembly: InternalsVisibleTo("SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests")] \ No newline at end of file +[assembly: InternalsVisibleTo("SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests")] \ No newline at end of file diff --git a/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Utilities/Internal/FileHttpContentBuilder.cs b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Utilities/Internal/FileHttpContentBuilder.cs new file mode 100644 index 00000000..446397f4 --- /dev/null +++ b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Utilities/Internal/FileHttpContentBuilder.cs @@ -0,0 +1,43 @@ +using System; +using System.Net.Http; +using System.Net.Http.Headers; +using System.Text; +using System.Web; + +namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.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, (_) => { }, (_) => { }); + } + + public static MultipartFormDataContent Build(string fileName, byte[] fileBytes, string fileContentType, string fileMetaJson, string formDataName, Action configureMetaHttpContent, Action configureFileHttpContent) + { + if (fileName == null) throw new ArgumentNullException(nameof(fileName)); + if (fileMetaJson == null) throw new ArgumentNullException(nameof(fileMetaJson)); + if (formDataName == null) throw new ArgumentNullException(nameof(formDataName)); + if (configureFileHttpContent == null) throw new ArgumentNullException(nameof(configureFileHttpContent)); + + fileBytes = fileBytes ?? Array.Empty(); + fileContentType = string.IsNullOrEmpty(fileContentType) ? "application/octet-stream" : fileContentType; + formDataName = formDataName.Replace("\"", ""); + + ByteArrayContent metaContent = new ByteArrayContent(Encoding.UTF8.GetBytes(fileMetaJson)); + metaContent.Headers.ContentType = MediaTypeHeaderValue.Parse("application/json"); + configureMetaHttpContent(metaContent); + + ByteArrayContent fileContent = new ByteArrayContent(fileBytes); + fileContent.Headers.ContentType = MediaTypeHeaderValue.Parse(fileContentType); + configureFileHttpContent(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.Add(metaContent, $"\"{Constants.FormDataFields.FORMDATA_META}\""); + httpContent.Add(fileContent, $"\"{formDataName}\"", $"\"{HttpUtility.UrlEncode(fileName)}\""); + return httpContent; + } + } +}