abp icon indicating copy to clipboard operation
abp copied to clipboard

Support list/enumrable of complex types for ABP dynamic/static c# proxies on GET requests

Open hikalkan opened this issue 4 months ago • 5 comments

Currently, it can not properly convert these kind of objects to query string parameters. Example method parameter:


// APP SERVICE METHOD:

public async Task<PagedResultDto<Dictionary<string, object?>>> GetListAsync(DynamicEntityListRequestDto input)

// METHOD PARAM

public class DynamicEntityListRequestDto : PagedResultRequestDto
{
    public string EntityName { get; set; }
    
    public List<DynamicQuerySortArgs>? Sortings { get; set; }
}

public class DynamicQuerySortArgs
{
    public string PropertyName { get; set; }
    public bool IsDescending { get; set; }
}

Now the request is made like that:

https://localhost:44337/api/app/dynamic-entity?
EntityName=LowCodeDemo.Customers.Customer&
Sortings[0]=LowCodeDemo.LowCode.DynamicQuerySortArgs&
SkipCount=0&MaxResultCount=10&api-version=1.0

So, it makes ToString() for the LowCodeDemo.LowCode.DynamicQuerySortArgs object, but it should send its values properly.

hikalkan avatar Aug 19 '25 13:08 hikalkan

We can't convert all types to query strings,formdata, or path correctly. So we have provided IObjectToQueryString/IObjectToFormData/IObjectToPath for developers to implement themselves.

Add a class that implements the IObjectToQueryString<DynamicEntityListRequestDto>, build the query string yourself, and add it to AbpHttpClientProxyingOptions's QueryStringConverts.

https://github.com/abpframework/abp/blob/dev/framework/src/Volo.Abp.Http.Client/Volo/Abp/Http/Client/ClientProxying/IObjectToQueryString.cs https://github.com/abpframework/abp/blob/dev/framework/src/Volo.Abp.Http.Client/Volo/Abp/Http/Client/ClientProxying/ExtraPropertyDictionaryConverts/ExtraPropertyDictionaryToQueryString.cs https://github.com/abpframework/abp/blob/dev/framework/src/Volo.Abp.Http.Client/Volo/Abp/Http/Client/AbpHttpClientModule.cs#L34-L38

maliming avatar Aug 19 '25 13:08 maliming

@maliming it didn't work smoothly, because HttpActionParameterHelper.FindParameterValue also couldn't properly retrieve the value.

Anyway, I think we can handle enumrable of any type with reflection, at least one level depth.

hikalkan avatar Aug 19 '25 17:08 hikalkan

because HttpActionParameterHelper.FindParameterValue also couldn't properly retrieve the value.

I will try to reproduce it to resolve the problem.

maliming avatar Aug 20 '25 00:08 maliming

Adding IObjectToQueryString<List<DynamicQuerySortArgs>> can solve this case.

var input = new DynamicEntityListRequestDto()
{
    EntityName = "Person",
    Sortings = new List<DynamicQuerySortArgs>()
    {
        new DynamicQuerySortArgs() {PropertyName = "Name", IsDescending = false},
        new DynamicQuerySortArgs() {PropertyName = "Age", IsDescending = true}
    }
};
public class DynamicQuerySortArgsToQueryString : IObjectToQueryString<List<DynamicQuerySortArgs>>, ITransientDependency
{
    public Task<string> ConvertAsync(ActionApiDescriptionModel actionApiDescription, ParameterApiDescriptionModel parameterApiDescription, List<DynamicQuerySortArgs> values)
    {
        if (values.IsNullOrEmpty())
        {
            return Task.FromResult<string>(null);
        }

        var sb = new StringBuilder();
        for (var i = 0; i < values.Count; i++)
        {
            sb.Append($"Sortings[{i}].PropertyName={values[i].PropertyName}&Sortings[{i}].IsDescending={values[i].IsDescending}&");
        }
        sb.Remove(sb.Length - 1, 1);
        return Task.FromResult(sb.ToString());
    }
}

Configure<AbpHttpClientProxyingOptions>(options =>
{
    options.QueryStringConverts.Add(typeof(List<DynamicQuerySortArgs>), typeof(DynamicQuerySortArgsToQueryString));
});

/api/app/dynamic-entity?EntityName=Person&Sortings[0].PropertyName=Name&Sortings[0].IsDescending=False&Sortings[1].PropertyName=Age&Sortings[1].IsDescending=True&SkipCount=0&MaxResultCount=10&api-version=1.0

Image

maliming avatar Aug 20 '25 03:08 maliming

Thanks for your suggestion

hikalkan avatar Aug 20 '25 06:08 hikalkan