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

如何将含集合的JSON反序列化为C# Protobuf对象?

解决方案

方案1:使用Protobuf官方JSON解析器(推荐)

Protobuf官方提供了原生的JSON序列化/反序列化工具,完美支持RepeatedField<T>类型,无需额外配置:

  1. 安装NuGet包:Google.Protobuf 和 Google.Protobuf.Json
  2. 代码示例:
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>:

  1. 安装NuGet包:Newtonsoft.Json
  2. 编写转换器:
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);
    }
}
  1. 反序列化时使用转换器:
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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 16:00:59