You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将嵌套对象转换为带扁平化参数名的查询字符串?

嵌套C#对象转带层级前缀的查询字符串问题

我需要把下面的嵌套请求对象转换成指定格式的查询字符串:

var parameter = new RulesCommandServiceAppendRequest()
{
    Chain = Chain.INPUT,
    Data = new RuleInputModel()
    {
        Protocol = "tcp",
        SourceIp = "2.2.2.2",
        DestinationIp = "1.1.1.1",
        SourcePort = "111",
        DestinationPort = "222",
        Jump = "DROP"
    }
};

期望的查询字符串格式:

Chain=INPUT&Data.DestinationIp=1.1.1.1&Data.DestinationPort=222&Data.Jump=DROP&Data.Protocol=tcp&Data.SourceIp=2.2.2.2&Data.SourcePort=111

我尝试用WebSerializer库调用WebSerializer.ToQueryString(parameter),得到的结果不符合预期:

Chain=INPUT&Data=DestinationIp=1.1.1.1&DestinationPort=222&Jump=DROP&Protocol=tcp&SourceIp=2.2.2.2&SourcePort=111

这个结果无法被我的ASP.NET Web API .NET 6服务端识别,请问有没有其他可用的库,或者修正WebSerializer使用方式的技巧?


可行解决方案

1. 手动构建键值对生成查询字符串

直接用System.Net.Http的FormUrlEncodedContent手动拼接带层级前缀的键值对,简单直接:

var keyValuePairs = new List<KeyValuePair<string, string>>
{
    new("Chain", parameter.Chain.ToString()),
    new("Data.Protocol", parameter.Data.Protocol),
    new("Data.SourceIp", parameter.Data.SourceIp),
    new("Data.DestinationIp", parameter.Data.DestinationIp),
    new("Data.SourcePort", parameter.Data.SourcePort),
    new("Data.DestinationPort", parameter.Data.DestinationPort),
    new("Data.Jump", parameter.Data.Jump)
};

var content = new FormUrlEncodedContent(keyValuePairs);
string queryString = await content.ReadAsStringAsync();

2. 用Newtonsoft.Json递归生成嵌套格式

利用Newtonsoft.Json的序列化能力,递归遍历对象结构生成带层级的键值对:

using Newtonsoft.Json.Linq;

public static string ToNestedQueryString(object obj, string prefix = "")
{
    var properties = JObject.FromObject(obj);
    var keyValuePairs = new List<string>();

    foreach (var prop in properties)
    {
        var key = string.IsNullOrEmpty(prefix) ? prop.Key : $"{prefix}.{prop.Key}";
        
        if (prop.Value is JObject nestedObj)
        {
            keyValuePairs.Add(ToNestedQueryString(nestedObj, key));
        }
        else
        {
            var value = Uri.EscapeDataString(prop.Value.ToString());
            keyValuePairs.Add($"{key}={value}");
        }
    }

    return string.Join("&", keyValuePairs);
}

// 使用示例
string queryString = ToNestedQueryString(parameter);

3. 用ASP.NET Core工具类结合反射展开对象

借助Microsoft.AspNetCore.WebUtilities的QueryHelpers,配合反射递归扁平化嵌套对象:

using System.Reflection;
using Microsoft.AspNetCore.WebUtilities;

public static Dictionary<string, string> FlattenObject(object obj, string prefix = "")
{
    var result = new Dictionary<string, string>();
    foreach (PropertyInfo prop in obj.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance))
    {
        var value = prop.GetValue(obj);
        if (value == null) continue;

        var key = string.IsNullOrEmpty(prefix) ? prop.Name : $"{prefix}.{prop.Name}";
        
        if (prop.PropertyType.IsClass && prop.PropertyType != typeof(string))
        {
            var nestedDict = FlattenObject(value, key);
            foreach (var nestedKvp in nestedDict)
            {
                result[nestedKvp.Key] = nestedKvp.Value;
            }
        }
        else
        {
            result[key] = value.ToString();
        }
    }
    return result;
}

// 使用示例
var flattened = FlattenObject(parameter);
string queryString = QueryHelpers.AddQueryString("", flattened);

4. 调整WebSerializer配置(若支持)

检查WebSerializer是否支持自定义嵌套格式配置:比如给RuleInputModel的属性添加前缀注解,或者修改全局序列化契约,让嵌套对象的属性自动带上父级属性名作为前缀。如果库本身提供这类配置,调整后即可生成符合要求的格式。


内容的提问来源于stack exchange,提问作者sorosh_sabz

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.13 21:35:14