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

C#中如何将包含字典属性的数据模型的JSON输出扁平化?

可行实现方案

以下提供三种常用实现方式,均可直接输出你需要的完全扁平化JSON结构:

方案1:使用Newtonsoft.Json(Json.NET)自定义转换器

这是最常用的实现方式,无需额外生成中间对象,序列化时直接展开结构:

using Newtonsoft.Json;

public class PersonFlattenConverter : JsonConverter<Person>
{
    public override void WriteJson(JsonWriter writer, Person value, JsonSerializer serializer)
    {
        writer.WriteStartObject();
        // 写入Person类原生属性
        writer.WritePropertyName(nameof(Person.Name));
        writer.WriteValue(value.Name);
        writer.WritePropertyName(nameof(Person.DOB));
        // 日期格式可根据需求调整,不需要固定格式可直接传value.DOB
        writer.WriteValue(value.DOB.ToString("dd/MM/yyyy"));
        // 展开Address字典的所有键值对
        foreach (var kvp in value.Address)
        {
            writer.WritePropertyName(kvp.Key);
            writer.WriteValue(kvp.Value);
        }
        writer.WriteEndObject();
    }

    public override Person ReadJson(JsonReader reader, Type objectType, Person existingValue, bool hasExistingValue, JsonSerializer serializer)
    {
        throw new NotImplementedException("当前转换器仅支持序列化操作");
    }
}

使用示例:

// 构造测试数据
var person = new Person
{
    Name = "Jim",
    DOB = new DateTime(1990,1,21),
    Address = new Dictionary<string, string>
    {
        {"Number", "18"},
        {"Line1", "Knotta Street"},
        {"Line2", "Thrumpton-on-Thames"},
        {"Postcode", "SW1 2AA"}
    }
};
// 序列化时指定自定义转换器
string json = JsonConvert.SerializeObject(person, Formatting.Indented, new PersonFlattenConverter());

方案2:使用.NET官方System.Text.Json自定义转换器

适合不想引入第三方库的场景,实现逻辑和Json.NET类似:

using System.Text.Json;
using System.Text.Json.Serialization;

public class PersonFlattenConverter : JsonConverter<Person>
{
    public override void Write(Utf8JsonWriter writer, Person value, JsonSerializerOptions options)
    {
        writer.WriteStartObject();
        writer.WriteString(nameof(Person.Name), value.Name);
        // 日期格式可按需调整
        writer.WriteString(nameof(Person.DOB), value.DOB.ToString("dd/MM/yyyy"));
        foreach (var kvp in value.Address)
        {
            writer.WriteString(kvp.Key, kvp.Value);
        }
        writer.WriteEndObject();
    }

    public override Person Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
    {
        throw new NotImplementedException("当前转换器仅支持序列化操作");
    }
}

使用示例:

var options = new JsonSerializerOptions { WriteIndented = true };
options.Converters.Add(new PersonFlattenConverter());
string json = JsonSerializer.Serialize(person, options);

方案3:动态构建扁平化匿名对象

如果确实需要先得到中间的扁平化对象再序列化,可以用ExpandoObject动态构建:

using System.Dynamic;

public static dynamic FlattenPerson(Person person)
{
    IDictionary<string, object> flatObj = new ExpandoObject();
    flatObj[nameof(Person.Name)] = person.Name;
    flatObj[nameof(Person.DOB)] = person.DOB.ToString("dd/MM/yyyy");
    foreach (var kvp in person.Address)
    {
        flatObj[kvp.Key] = kvp.Value;
    }
    return flatObj;
}

使用示例:

dynamic flatPerson = FlattenPerson(person);
// 可以直接序列化该对象得到目标JSON
string json = JsonConvert.SerializeObject(flatPerson, Formatting.Indented);

注意事项

如果Address字典的键可能和Person类原生属性(Name、DOB)重名,建议提前添加校验逻辑,避免属性覆盖。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 06:24:04