如何用Newtonsoft.Json序列化含内部对象的Dictionary<string, string>及指定字典为JSON?
序列化含复杂对象的字典及指定格式序列化方案
首先得澄清下:你提到的Dictionary<string, string>本身的value是字符串类型,不存在“内部对象”的情况——如果是笔误,实际是指值包含自定义对象/复杂类型的字典(比如Dictionary<string, YourCustomClass>或Dictionary<string, object>),那完全有成熟的解决办法,而且用Newtonsoft.Json(Json.NET)就能轻松搞定!
一、序列化包含内部对象的字典
假设你有一个自定义的内部对象类,比如:
public class OrderDetail { public string ProductName { get; set; } public int Quantity { get; set; } public decimal Price { get; set; } }
你的字典是Dictionary<string, OrderDetail>类型,序列化代码非常直观:
// 构造示例字典 var orderDict = new Dictionary<string, OrderDetail> { ["order_001"] = new OrderDetail { ProductName = "Laptop", Quantity = 1, Price = 999.99m }, ["order_002"] = new OrderDetail { ProductName = "Mouse", Quantity = 2, Price = 29.99m } }; // 执行序列化,带缩进让格式更清晰 string jsonResult = JsonConvert.SerializeObject(orderDict, Formatting.Indented);
得到的JSON输出会是:
{ "order_001": { "ProductName": "Laptop", "Quantity": 1, "Price": 999.99 }, "order_002": { "ProductName": "Mouse", "Quantity": 2, "Price": 29.99 } }
如果是Dictionary<string, object>这种混合了多种类型的字典,Json.NET也能自动识别并正确序列化,除非涉及到特别小众的类型,才需要额外配置自定义转换器。
二、将目标字典序列化为指定JSON格式
当然可以!Newtonsoft.Json提供了极强的自定义能力,能满足几乎所有指定格式的需求,下面举几个常见场景:
1. 调整命名风格、忽略空值
比如你需要输出驼峰命名的JSON,同时忽略值为null的属性:
var settings = new JsonSerializerSettings { Formatting = Formatting.Indented, ContractResolver = new CamelCasePropertyNamesContractResolver(), // 驼峰命名 NullValueHandling = NullValueHandling.Ignore // 忽略空值属性 }; string styledJson = JsonConvert.SerializeObject(orderDict, settings);
输出会变成:
{ "order_001": { "productName": "Laptop", "quantity": 1, "price": 999.99 }, "order_002": { "productName": "Mouse", "quantity": 2, "price": 29.99 } }
2. 自定义字典的结构输出
比如你不想把字典序列化为键值对对象,而是序列化为包含key和value字段的数组,这时候可以自定义转换器:
public class CustomDictConverter : JsonConverter<Dictionary<string, OrderDetail>> { public override void WriteJson(JsonWriter writer, Dictionary<string, OrderDetail> value, JsonSerializer serializer) { writer.WriteStartArray(); foreach (var kvp in value) { writer.WriteStartObject(); writer.WritePropertyName("orderId"); // 自定义键名 writer.WriteValue(kvp.Key); writer.WritePropertyName("detail"); // 自定义值字段名 serializer.Serialize(writer, kvp.Value); writer.WriteEndObject(); } writer.WriteEndArray(); } // 如果需要反序列化,再实现ReadJson方法即可 public override Dictionary<string, OrderDetail> ReadJson(JsonReader reader, Type objectType, Dictionary<string, OrderDetail> existingValue, bool hasExistingValue, JsonSerializer serializer) { throw new NotImplementedException("反序列化逻辑需按需实现"); } }
使用时指定转换器:
string customFormatJson = JsonConvert.SerializeObject(orderDict, new CustomDictConverter());
输出就会变成你想要的数组结构:
[ { "orderId": "order_001", "detail": { "ProductName": "Laptop", "Quantity": 1, "Price": 999.99 } }, { "orderId": "order_002", "detail": { "ProductName": "Mouse", "Quantity": 2, "Price": 29.99 } } ]
总结
- 如果是
Dictionary<string, string>,直接序列化就是简单的键值对JSON;如果是值为复杂对象的字典,Json.NET完全支持直接序列化。 - 要实现指定格式,通过
JsonSerializerSettings做基础配置,或者自定义JsonConverter做深度定制,就能达成你想要的输出效果。
内容的提问来源于stack exchange,提问作者Pavlo Datsiuk
相关产品推荐
相关产品推荐

