将字符串反序列化为 *.proto 中定义的对象时出错?

Posted

技术标签:

【中文标题】将字符串反序列化为 *.proto 中定义的对象时出错?【英文标题】:Get error when deserializing a string to object defined in *.proto? 【发布时间】:2019-11-29 09:58:03 【问题描述】:

请注意该对象是在 proto 文件中定义的,而不是在普通的 cs 文件中。它有不同的行为。

我正在使用 c#。我的原型文件的一部分是:

    message CodeDependency 
        string path = 1;
        DependencyType type = 2;

        enum DependencyType 
            NONE = 0;
            TAR = 1;
            ZIP = 2;
            TAR_GZ = 3;
            DIRECTORY = 4;
        
    

我有一个 json 字符串:

"codeDependency": 
                    "path": "/CAP_TEST/job_manager/modules/1c8185d5-2add-4bd4-a332-8b21a6819608/tmpr9z7xinh.tar.gz",
                    "type": "TAR_GZ"
                

我尝试了三种反序列化方法:

Newtonsoft.Json.JsonConvert.DeserializeObject<CodeDependency>
CodeDependency.Parser.ParseFrom
ProtoBuf.Serializer.Deserialize<CodeDependency>

它们都不起作用。从错误消息来看,似乎无法反序列化“TAR_GZ”。

Error converting value "TAR_GZ" to type 'Microsoft.ABC.GRPC.Modules.Module+Types+CodeDependency+Types+DependencyType'. Path 'graph.nodes[4].module.codeDependency.type', line 273, position 21. ---> System.ArgumentException: Requested value 'TAR_GZ' was not found

如果我将“TAR_GZ”更改为“TAR”,就可以了。那么问题可能与“TAR_GZ”中的下划线有关?有没有办法在 C# 中解决它? (在python中没问题。)感谢您的帮助!

【问题讨论】:

试试 NewtonsoftJson:nuget.org/packages/Newtonsoft.Json @MaxMustermann 他已经拥有了 这能回答你的问题吗? Can't get enum to convert to json properly using Json.NET 如果你序列化包含你想要的数据的protobuf消息,你会得到什么? (转 JSON) 感谢您的 cmets。我试过(Newtonsoft.Json)JsonConvert.DeserializeObject。问题是:对于通用 cs 文件中定义的类(和枚举),它工作正常。但是对于在 *.proto 中定义的类(并由 protobuf dll 编译为 cs),它不起作用。错误消息是“将值“TAR_GZ”转换为类型“Microsoft.ABC.GRPC.Modules.Module+Types+CodeDependency+Types+DependencyType”时出错。路径“graph.nodes[4].module.codeDependency.type”,行273,位置 21。---> System.ArgumentException: 未找到请求的值 'TAR_GZ'" 【参考方案1】:

我已经用 NewtonsoftJson 和一个根对象尝试过你的问题,这对我有用 这是我的解决方案:

    namespace RegexTests

    static class StringExtension
    
        public static T DeserializeJson<T>(this string toSerialize)
        
            return Newtonsoft.Json.JsonConvert.DeserializeObject<T>(toSerialize, new Newtonsoft.Json.JsonSerializerSettings()
            
                TypeNameHandling = Newtonsoft.Json.TypeNameHandling.Auto
            );
        
    

    class Root
    
        public CodeDependency CodeDependency  get; set; 
    

    class CodeDependency
    
        public string Path  get; set; 
        public DependencyType Type  get; set; 
    

    enum DependencyType
    
        NONE = 0,
        TAR = 1,
        ZIP = 2,
        TAR_GZ = 3,
        DIRECTORY = 4,
    

    class Program
    


        static void Main(string[] args)
        
            string json = "\"CodeDependency\":  \"Path\": \"/CAP_TEST/job_manager/modules/1c8185d5-2add-4bd4-a332-8b21a6819608/tmpr9z7xinh.tar.gz\", \"Type\": \"TAR_GZ\"  ";


            var obj = json.DeserializeJson<Root>();

            Console.WriteLine();
            Console.ReadLine();
        
    

【讨论】:

谢谢马克斯。我试过 JsonConvert.DeserializeObject。对于在通用 cs 文件中定义的类(和枚举),它工作正常。但是对于 *.proto 中定义的类(并通过 protobuf dll 编译为 cs),它不起作用

以上是关于将字符串反序列化为 *.proto 中定义的对象时出错?的主要内容,如果未能解决你的问题,请参考以下文章

将 xml 反序列化为对象时出错:System.FormatException 输入字符串格式不正确

需要帮助将 XML 文件反序列化为对象 C#

将cXML反序列化为C#类

将 Web 服务 API 中的 XML 字符串反序列化为 C# 对象

无法将 JSON 字符串反序列化为 C# 对象

如何使用json.net自定义反序列化为对象