如何将含集合的JSON反序列化为C# Protobuf对象?
解决方案
方案1:使用Protobuf官方JSON解析器(推荐)
Protobuf官方提供了原生的JSON序列化/反序列化工具,完美支持RepeatedField<T>类型,无需额外配置:
- 安装NuGet包:
Google.Protobuf和Google.Protobuf.Json - 代码示例:
using Google.Protobuf; using Google.Protobuf.Json; using System.IO; // 读取JSON文件 string jsonContent = File.ReadAllText("your-file-path.json"); // 反序列化为Person对象 Person person = JsonParser.Default.Parse<Person>(jsonContent); // 验证结果 foreach (var loc in person.PlacesTravelled) { Console.WriteLine($"{loc.Country} - {loc.City}"); }
方案2:为Newtonsoft.Json自定义转换器
如果项目依赖Newtonsoft.Json,需要自定义转换器处理RepeatedField<T>:
- 安装NuGet包:
Newtonsoft.Json - 编写转换器:
using Google.Protobuf.Collections; using Newtonsoft.Json; using System; using System.Collections.Generic; public class RepeatedFieldConverter<T> : JsonConverter<RepeatedField<T>> { public override RepeatedField<T> ReadJson(JsonReader reader, Type objectType, RepeatedField<T> existingValue, bool hasExistingValue, JsonSerializer serializer) { var list = serializer.Deserialize<List<T>>(reader); var repeatedField = new RepeatedField<T>(); repeatedField.AddRange(list); return repeatedField; } public override void WriteJson(JsonWriter writer, RepeatedField<T> value, JsonSerializer serializer) { serializer.Serialize(writer, value); } }
- 反序列化时使用转换器:
using Newtonsoft.Json; using System.IO; string jsonContent = File.ReadAllText("your-file-path.json"); var settings = new JsonSerializerSettings { Converters = { new RepeatedFieldConverter<Location>() } }; Person person = JsonConvert.DeserializeObject<Person>(jsonContent, settings);
问题原因
Protobuf生成的C#类中,repeated字段会被编译为RepeatedField<T>类型——这是Protobuf自定义的只读集合类型,普通JSON序列化器(如Newtonsoft.Json)无法识别其内部结构,默认会跳过对只读属性的赋值,导致重复字段最终为null。
内容的提问来源于stack exchange,提问作者AS3
相关产品推荐
相关产品推荐

