From 388746ecf656ca015cc30d7ccce3339d40dfc79a Mon Sep 17 00:00:00 2001 From: maliming Date: Fri, 22 Sep 2023 13:58:27 +0800 Subject: [PATCH] Add `ExtraPropertyDictionaryToQueryString/FormData`. --- .../Abp/Http/Client/AbpHttpClientModule.cs | 12 +++++- .../ExtraPropertyDictionaryToFormData.cs | 28 +++++++++++++ .../ExtraPropertyDictionaryToQueryString.cs | 31 ++++++++++++++ .../PersonAppServiceClientProxy_Tests.cs | 42 +++++++++++-------- .../DynamicProxying/TestObjectToFormData.cs | 5 +++ .../TestObjectToQueryString.cs | 4 ++ .../TestApp/Application/Dto/GetParamsInput.cs | 5 ++- .../TestApp/Application/PeopleAppService.cs | 14 ++++--- 8 files changed, 114 insertions(+), 27 deletions(-) create mode 100644 framework/src/Volo.Abp.Http.Client/Volo/Abp/Http/Client/ClientProxying/ExtraPropertyDictionaryConverts/ExtraPropertyDictionaryToFormData.cs create mode 100644 framework/src/Volo.Abp.Http.Client/Volo/Abp/Http/Client/ClientProxying/ExtraPropertyDictionaryConverts/ExtraPropertyDictionaryToQueryString.cs diff --git a/framework/src/Volo.Abp.Http.Client/Volo/Abp/Http/Client/AbpHttpClientModule.cs b/framework/src/Volo.Abp.Http.Client/Volo/Abp/Http/Client/AbpHttpClientModule.cs index dc14ee4203..c0dfeabbd1 100644 --- a/framework/src/Volo.Abp.Http.Client/Volo/Abp/Http/Client/AbpHttpClientModule.cs +++ b/framework/src/Volo.Abp.Http.Client/Volo/Abp/Http/Client/AbpHttpClientModule.cs @@ -1,11 +1,15 @@ -using Microsoft.Extensions.DependencyInjection; +using System.Collections.Generic; +using Microsoft.Extensions.DependencyInjection; using Volo.Abp.Castle; +using Volo.Abp.Data; using Volo.Abp.EventBus; using Volo.Abp.Modularity; using Volo.Abp.MultiTenancy; using Volo.Abp.Threading; using Volo.Abp.Validation; using Volo.Abp.ExceptionHandling; +using Volo.Abp.Http.Client.ClientProxying; +using Volo.Abp.Http.Client.ClientProxying.ExtraPropertyDictionaryConverts; using Volo.Abp.Http.Client.DynamicProxying; using Volo.Abp.RemoteServices; @@ -27,5 +31,11 @@ public override void ConfigureServices(ServiceConfigurationContext context) { context.Services.AddHttpClient(); context.Services.AddTransient(typeof(DynamicHttpProxyInterceptorClientProxy<>)); + + Configure(options => + { + options.QueryStringConverts.Add(typeof(ExtraPropertyDictionary), typeof(ExtraPropertyDictionaryToQueryString)); + options.FormDataConverts.Add(typeof(ExtraPropertyDictionary), typeof(ExtraPropertyDictionaryToFormData)); + }); } } diff --git a/framework/src/Volo.Abp.Http.Client/Volo/Abp/Http/Client/ClientProxying/ExtraPropertyDictionaryConverts/ExtraPropertyDictionaryToFormData.cs b/framework/src/Volo.Abp.Http.Client/Volo/Abp/Http/Client/ClientProxying/ExtraPropertyDictionaryConverts/ExtraPropertyDictionaryToFormData.cs new file mode 100644 index 0000000000..72cfb55156 --- /dev/null +++ b/framework/src/Volo.Abp.Http.Client/Volo/Abp/Http/Client/ClientProxying/ExtraPropertyDictionaryConverts/ExtraPropertyDictionaryToFormData.cs @@ -0,0 +1,28 @@ +using System.Collections.Generic; +using System.Net.Http; +using System.Text; +using System.Threading.Tasks; +using Volo.Abp.Data; +using Volo.Abp.DependencyInjection; +using Volo.Abp.Http.Modeling; + +namespace Volo.Abp.Http.Client.ClientProxying.ExtraPropertyDictionaryConverts; + +public class ExtraPropertyDictionaryToFormData : IObjectToFormData, ITransientDependency +{ + public Task>> ConvertAsync(ActionApiDescriptionModel actionApiDescription, ParameterApiDescriptionModel parameterApiDescription, ExtraPropertyDictionary extraPropertyDictionary) + { + if (extraPropertyDictionary.IsNullOrEmpty()) + { + return Task.FromResult>>(null!); + } + + var formDataContents = new List>(); + foreach (var item in extraPropertyDictionary) + { + formDataContents.Add(new KeyValuePair($"ExtraProperties[{item.Key}]", new StringContent(item.Value!.ToString()!, Encoding.UTF8))); + } + + return Task.FromResult(formDataContents); + } +} diff --git a/framework/src/Volo.Abp.Http.Client/Volo/Abp/Http/Client/ClientProxying/ExtraPropertyDictionaryConverts/ExtraPropertyDictionaryToQueryString.cs b/framework/src/Volo.Abp.Http.Client/Volo/Abp/Http/Client/ClientProxying/ExtraPropertyDictionaryConverts/ExtraPropertyDictionaryToQueryString.cs new file mode 100644 index 0000000000..a1b2919615 --- /dev/null +++ b/framework/src/Volo.Abp.Http.Client/Volo/Abp/Http/Client/ClientProxying/ExtraPropertyDictionaryConverts/ExtraPropertyDictionaryToQueryString.cs @@ -0,0 +1,31 @@ +using System.Collections.Generic; +using System.Text; +using System.Threading.Tasks; +using Volo.Abp.Data; +using Volo.Abp.DependencyInjection; +using Volo.Abp.Http.Modeling; + +namespace Volo.Abp.Http.Client.ClientProxying.ExtraPropertyDictionaryConverts; + +public class ExtraPropertyDictionaryToQueryString : IObjectToQueryString, ITransientDependency +{ + public Task ConvertAsync(ActionApiDescriptionModel actionApiDescription, ParameterApiDescriptionModel parameterApiDescription, ExtraPropertyDictionary extraPropertyDictionary) + { + if (extraPropertyDictionary.IsNullOrEmpty()) + { + return Task.FromResult(null!); + } + + var sb = new StringBuilder(); + foreach (var item in extraPropertyDictionary) + { + sb.Append($"ExtraProperties[{item.Key}]={item.Value}&"); + } + if (sb.Length > 0) + { + sb.Remove(sb.Length - 1, 1); + } + + return Task.FromResult(sb.ToString()); + } +} diff --git a/framework/test/Volo.Abp.Http.Client.Tests/Volo/Abp/Http/DynamicProxying/PersonAppServiceClientProxy_Tests.cs b/framework/test/Volo.Abp.Http.Client.Tests/Volo/Abp/Http/DynamicProxying/PersonAppServiceClientProxy_Tests.cs index fbaf6b4d3e..7671dcf0cb 100644 --- a/framework/test/Volo.Abp.Http.Client.Tests/Volo/Abp/Http/DynamicProxying/PersonAppServiceClientProxy_Tests.cs +++ b/framework/test/Volo.Abp.Http.Client.Tests/Volo/Abp/Http/DynamicProxying/PersonAppServiceClientProxy_Tests.cs @@ -12,6 +12,7 @@ using Volo.Abp.Application.Dtos; using Volo.Abp.AspNetCore.Mvc.Conventions; using Volo.Abp.Content; +using Volo.Abp.Data; using Volo.Abp.Domain.Repositories; using Volo.Abp.Http.Client; using Volo.Abp.TestApp.Application; @@ -280,7 +281,7 @@ public async Task CreateMultipleFileAsync() [Fact] public async Task GetParamsFromQueryAsync() { - var result = await _peopleAppService.GetParamsFromQueryAsync(new GetParamsInput() + var input = new GetParamsInput() { NameValues = new List() { @@ -300,34 +301,39 @@ public async Task GetParamsFromQueryAsync() Name = "name3", Value = "value3" } - }); - result.ShouldBe("name1-value1:name2-value2:name3-value3"); + }; + input.SetProperty("TestProperty", "TestPropertyValue"); + foreach (var nameValue in input.NameValues) + { + nameValue.SetProperty("TestPropertyInList", "TestPropertyValueInList"); + } + + var result = await _peopleAppService.GetParamsFromQueryAsync(input); + result.ShouldBe("name1-value1:TestPropertyValueInList:name2-value2:name3-value3:TestPropertyValue"); } [Fact] public async Task GetParamsFromFormAsync() { - var result = await _peopleAppService.GetParamsFromFormAsync(new GetParamsInput() + var input = new GetParamsInput() { NameValues = new List() { - new GetParamsNameValue() - { - Name = "name1", - Value = "value1" - }, - new GetParamsNameValue() - { - Name = "name2", - Value = "value2" - } + new GetParamsNameValue() {Name = "name1", Value = "value1"}, + new GetParamsNameValue() {Name = "name2", Value = "value2"} }, NameValue = new GetParamsNameValue() { - Name = "name3", - Value = "value3" + Name = "name3", Value = "value3" } - }); - result.ShouldBe("name1-value1:name2-value2:name3-value3"); + }; + input.SetProperty("TestProperty", "TestPropertyValue"); + foreach (var nameValue in input.NameValues) + { + nameValue.SetProperty("TestPropertyInList", "TestPropertyValueInList"); + } + + var result = await _peopleAppService.GetParamsFromFormAsync(input); + result.ShouldBe("name1-value1:TestPropertyValueInList:name2-value2:name3-value3:TestPropertyValue"); } } diff --git a/framework/test/Volo.Abp.Http.Client.Tests/Volo/Abp/Http/DynamicProxying/TestObjectToFormData.cs b/framework/test/Volo.Abp.Http.Client.Tests/Volo/Abp/Http/DynamicProxying/TestObjectToFormData.cs index 2c64773c88..9e3a5d28dd 100644 --- a/framework/test/Volo.Abp.Http.Client.Tests/Volo/Abp/Http/DynamicProxying/TestObjectToFormData.cs +++ b/framework/test/Volo.Abp.Http.Client.Tests/Volo/Abp/Http/DynamicProxying/TestObjectToFormData.cs @@ -23,6 +23,11 @@ public Task>> ConvertAsync(ActionApiDescr { formDataContents.Add(new KeyValuePair($"NameValues[{i}].Name", new StringContent(values[i].Name, Encoding.UTF8))); formDataContents.Add(new KeyValuePair($"NameValues[{i}].Value", new StringContent(values[i].Value, Encoding.UTF8))); + + foreach (var item in values[i].ExtraProperties) + { + formDataContents.Add(new KeyValuePair($"NameValues[{i}].ExtraProperties[{item.Key}]", new StringContent(item.Value!.ToString()!, Encoding.UTF8))); + } } return Task.FromResult(formDataContents); diff --git a/framework/test/Volo.Abp.Http.Client.Tests/Volo/Abp/Http/DynamicProxying/TestObjectToQueryString.cs b/framework/test/Volo.Abp.Http.Client.Tests/Volo/Abp/Http/DynamicProxying/TestObjectToQueryString.cs index d4ca6f7285..a27528cb77 100644 --- a/framework/test/Volo.Abp.Http.Client.Tests/Volo/Abp/Http/DynamicProxying/TestObjectToQueryString.cs +++ b/framework/test/Volo.Abp.Http.Client.Tests/Volo/Abp/Http/DynamicProxying/TestObjectToQueryString.cs @@ -22,6 +22,10 @@ public Task ConvertAsync(ActionApiDescriptionModel actionApiDescription, for (var i = 0; i < values.Count; i++) { sb.Append($"NameValues[{i}].Name={values[i].Name}&NameValues[{i}].Value={values[i].Value}&"); + foreach (var item in values[i].ExtraProperties) + { + sb.Append($"NameValues[{i}].ExtraProperties[{item.Key}]={item.Value}&"); + } } sb.Remove(sb.Length - 1, 1); diff --git a/framework/test/Volo.Abp.TestApp/Volo/Abp/TestApp/Application/Dto/GetParamsInput.cs b/framework/test/Volo.Abp.TestApp/Volo/Abp/TestApp/Application/Dto/GetParamsInput.cs index f9ca83d55d..6375a125a8 100644 --- a/framework/test/Volo.Abp.TestApp/Volo/Abp/TestApp/Application/Dto/GetParamsInput.cs +++ b/framework/test/Volo.Abp.TestApp/Volo/Abp/TestApp/Application/Dto/GetParamsInput.cs @@ -1,15 +1,16 @@ using System.Collections.Generic; +using Volo.Abp.ObjectExtending; namespace Volo.Abp.TestApp.Application.Dto; -public class GetParamsInput +public class GetParamsInput : ExtensibleObject { public List NameValues { get; set; } public GetParamsNameValue NameValue { get; set; } } -public class GetParamsNameValue +public class GetParamsNameValue : ExtensibleObject { public string Name { get; set; } diff --git a/framework/test/Volo.Abp.TestApp/Volo/Abp/TestApp/Application/PeopleAppService.cs b/framework/test/Volo.Abp.TestApp/Volo/Abp/TestApp/Application/PeopleAppService.cs index 752a548320..a7d64228bd 100644 --- a/framework/test/Volo.Abp.TestApp/Volo/Abp/TestApp/Application/PeopleAppService.cs +++ b/framework/test/Volo.Abp.TestApp/Volo/Abp/TestApp/Application/PeopleAppService.cs @@ -129,17 +129,19 @@ public async Task CreateMultipleFileAsync(CreateMultipleFileInput input) public Task GetParamsFromQueryAsync([FromQuery] GetParamsInput input) { - return Task.FromResult(input.NameValues?.FirstOrDefault()?.Name + "-" + - input.NameValues?.FirstOrDefault()?.Value + ":" + + return Task.FromResult(input.NameValues?.FirstOrDefault()?.Name + "-" + input.NameValues?.FirstOrDefault()?.Value + ":" + + input.NameValues?.FirstOrDefault()?.ExtraProperties["TestPropertyInList"] + ":" + input.NameValues?.LastOrDefault()?.Name + "-" + input.NameValues?.LastOrDefault()?.Value + ":" + - input.NameValue?.Name + "-" + input.NameValue?.Value); + input.NameValue?.Name + "-" + input.NameValue?.Value + ":" + + input.ExtraProperties["TestProperty"]); } public Task GetParamsFromFormAsync([FromForm] GetParamsInput input) { - return Task.FromResult(input.NameValues?.FirstOrDefault()?.Name + "-" + - input.NameValues?.FirstOrDefault()?.Value + ":" + + return Task.FromResult(input.NameValues?.FirstOrDefault()?.Name + "-" + input.NameValues?.FirstOrDefault()?.Value + ":" + + input.NameValues?.FirstOrDefault()?.ExtraProperties["TestPropertyInList"] + ":" + input.NameValues?.LastOrDefault()?.Name + "-" + input.NameValues?.LastOrDefault()?.Value + ":" + - input.NameValue?.Name + "-" + input.NameValue?.Value); + input.NameValue?.Name + "-" + input.NameValue?.Value + ":" + + input.ExtraProperties["TestProperty"]); } }