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

如何用Newtonsoft Json序列化含自定义对象键的字典为指定JSON

如何用Newtonsoft.Json正确序列化Dictionary<Employee, List>到指定JSON格式

你之前尝试用TypeConverter来处理Employee作为字典键的序列化,但这个思路不对——TypeConverter主要是给.NET框架做类型转换用的,Newtonsoft.Json用它的话也只是把键转成字符串,完全达不到你想要的把整个键值对展开成包含员工信息和车辆列表的对象结构。咱们换个正确的方式:用自定义JsonConverter来处理整个Dictionary<Employee, List<Car>>类型的序列化逻辑。

步骤1:修正Employee类

首先把Employee类上继承的TypeConverter去掉,它现在不需要这个:

public class Employee 
{ 
    public string Name { get; set; } 
    public string Id { get; set; } 
    public decimal Seniority { get; set; } 
} 

步骤2:创建自定义JsonConverter

这个转换器会遍历字典的每个键值对,把员工的属性和对应的车辆列表组合成你想要的JSON结构:

public class EmployeeCarDictionaryConverter : JsonConverter<Dictionary<Employee, List<Car>>>
{
    public override void WriteJson(JsonWriter writer, Dictionary<Employee, List<Car>> value, JsonSerializer serializer)
    {
        // 先写数组的开始标记
        writer.WriteStartArray();
        
        foreach (var kvp in value)
        {
            var employee = kvp.Key;
            var cars = kvp.Value;
            
            // 开始写单个员工的对象
            writer.WriteStartObject();
            
            // 写入员工的属性,注意Seniority要转成字符串
            writer.WritePropertyName("Name");
            serializer.Serialize(writer, employee.Name);
            
            writer.WritePropertyName("Seniority");
            serializer.Serialize(writer, employee.Seniority.ToString());
            
            // OwnerId对应Employee的Id字段
            writer.WritePropertyName("OwnerId");
            serializer.Serialize(writer, employee.Id);
            
            // 写入车辆列表
            writer.WritePropertyName("Cars");
            serializer.Serialize(writer, cars);
            
            // 结束单个员工对象
            writer.WriteEndObject();
        }
        
        // 结束数组
        writer.WriteEndArray();
    }

    public override Dictionary<Employee, List<Car>> ReadJson(JsonReader reader, Type objectType, Dictionary<Employee, List<Car>> existingValue, bool hasExistingValue, JsonSerializer serializer)
    {
        // 如果需要反序列化,可以在这里补充逻辑,示例先只实现序列化
        throw new NotImplementedException("Deserialization is not implemented for this converter.");
    }
}

步骤3:给Response的Dictionary属性标记转换器

在Response类的Dictionary属性上加上[JsonConverter]特性,指定咱们刚才写的自定义转换器:

public class Response 
{ 
    [JsonConverter(typeof(EmployeeCarDictionaryConverter))]
    public Dictionary<Employee, List<Car>> Dictionary { get; set; } 

    public class Car { 
        public string OwnerId { get; set; } 
        public string Model { get; set; } 
        public string RegistrationPlate { get; set; } 
    } 
}

步骤4:测试序列化

用示例数据测试一下,就能得到你想要的JSON结构了:

var response = new Response
{
    Dictionary = new Dictionary<Employee, List<Response.Car>>
    {
        {
            new Employee { Name = "John Doe", Id = "1111", Seniority = 2 },
            new List<Response.Car>
            {
                new Response.Car { OwnerId = "1111", Model = "Chevrolet Spark", RegistrationPlate = "LTO1234" },
                new Response.Car { OwnerId = "1111", Model = "Chevrolet Malibu", RegistrationPlate = "LTO5678" }
            }
        },
        {
            new Employee { Name = "Jane Doe", Id = "9999", Seniority = 10 },
            new List<Response.Car>
            {
                new Response.Car { OwnerId = "9999", Model = "Mercedes Benz", RegistrationPlate = "ABC1234" },
                new Response.Car { OwnerId = "9999", Model = "Mercedes Maybach", RegistrationPlate = "ABC5678" }
            }
        }
    }
};

var json = JsonConvert.SerializeObject(response, Formatting.Indented);
Console.WriteLine(json);

运行这段代码,输出的JSON就和你期望的结构完全一致了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 07:07:56