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

.NET环境下Proto2扩展字段反序列化失败问题求助

.NET中Proto2扩展字段反序列化失败(CQG集成场景)

问题描述

在.NET环境使用Protocol Buffers(Proto2)进行CQG集成时,遇到扩展字段反序列化问题:服务器已正确发送diagnostic_session_token扩展字段,但客户端始终无法解析该字段,单元测试也能复现此问题。

背景信息

CQG提供的诊断扩展proto定义如下:

syntax = "proto2";
package diagnostic_session_token_2;
option csharp_namespace = "CqgWebApi.DiagnosticSessionToken";

import "Proto/WebAPI/user_session_2.proto";
import "Proto/WebAPI/webapi_2.proto";

extend user_session_2.Logon
{
  optional bool include_diagnostic_session_token = 300;
}

extend WebAPI_2.ServerMsg
{
  optional string diagnostic_session_token = 300;
}

该扩展用于在服务器消息中附加诊断会话令牌,与LogonResult中的session_token一致。

服务器日志显示字段已正确传输(示例片段):

Message out: logon_result { ... } [diagnostic_session_token_2.diagnostic_session_token]: "0fWzz47ZC63k7Kfp5T2ja26yVeb9JTl89nZ3X0m5XbYnWomsknDAR+ugjOCBLw6++27dAGV5XhI" 

客户端核心代码片段:

async Task ProcessServerResponse(ServerMsg serverMsg)
{
    if (serverMsg.HasExtension(DiagnosticSessionToken2Extensions.DiagnosticSessionToken))
    {
        var sessionToken = serverMsg.GetExtension(DiagnosticSessionToken2Extensions.DiagnosticSessionToken);
        _logger.LogInformation("Session Token: {SessionToken}", sessionToken);
    }
    else
    {
        _logger.LogInformation("Session Token not present in the message."); // 始终进入此分支
    }
    ...
}

单元测试复现代码:

[Fact]
public void GivenServerMsgWithDiagnosticSessionToken_WhenSerializedAndDeserialized_ShouldContainToken()
{
    var expectedToken = "test_token";
    var serverMsg = new ServerMsg();
    serverMsg.SetExtension(DiagnosticSessionToken2Extensions.DiagnosticSessionToken, expectedToken);

    byte[] serializedData;
    using (var memoryStream = new MemoryStream())
    {
        serverMsg.WriteTo(memoryStream);
        serializedData = memoryStream.ToArray();
    }

    var deserializedServerMsg = ServerMsg.Parser.ParseFrom(serializedData);
    var actualToken = deserializedServerMsg.GetExtension(DiagnosticSessionToken2Extensions.DiagnosticSessionToken);

    actualToken.Should().Be(expectedToken); // 断言失败
}

可能原因与解决方案

1. 扩展字段未注册到解析器

Proto2的扩展需要显式注册到消息解析器中,否则解析时会被忽略。

解决方法:

  • 在应用初始化阶段(如Startup、客户端初始化逻辑)调用扩展注册方法:
    DiagnosticSessionToken2Extensions.RegisterAllExtensions();
    
  • 或者在解析消息时使用带扩展注册表的解析器:
    var registry = ExtensionRegistry.CreateInstance();
    DiagnosticSessionToken2Extensions.RegisterAllExtensions(registry);
    var deserializedServerMsg = ServerMsg.Parser.WithExtensionRegistry(registry).ParseFrom(serializedData);
    

2. Proto文件编译不完整

若编译Proto文件时未正确生成扩展相关代码,会导致客户端无法识别扩展字段。

解决方法:

  • 重新编译Proto文件,确保生成的DiagnosticSessionToken2Extensions类包含完整的注册逻辑,例如:
    public static void RegisterAllExtensions(Google.Protobuf.ExtensionRegistry registry)
    {
        registry.Add(IncludeDiagnosticSessionToken);
        registry.Add(DiagnosticSessionToken);
    }
    
  • 检查编译工具(如protoc、Grpc.Tools)的配置,确保import路径正确,未遗漏扩展定义的proto文件。

3. 字段编号或命名空间不匹配

若客户端与服务器端的扩展字段编号、命名空间不一致,会导致解析失败。

解决方法:

  • 核对客户端与服务器端的proto文件,确保:
    • 扩展字段编号(300)在ServerMsg的所有字段(含其他扩展)中唯一
    • package和csharp_namespace完全匹配,无拼写错误

4. 修改单元测试验证

将单元测试更新为使用带扩展注册表的解析器,验证修复效果:

[Fact]
public void GivenServerMsgWithDiagnosticSessionToken_WhenSerializedAndDeserialized_ShouldContainToken()
{
    var expectedToken = "test_token";
    var serverMsg = new ServerMsg();
    serverMsg.SetExtension(DiagnosticSessionToken2Extensions.DiagnosticSessionToken, expectedToken);

    byte[] serializedData;
    using (var memoryStream = new MemoryStream())
    {
        serverMsg.WriteTo(memoryStream);
        serializedData = memoryStream.ToArray();
    }

    // 使用带扩展注册表的解析器
    var registry = ExtensionRegistry.CreateInstance();
    DiagnosticSessionToken2Extensions.RegisterAllExtensions(registry);
    var deserializedServerMsg = ServerMsg.Parser.WithExtensionRegistry(registry).ParseFrom(serializedData);
    var actualToken = deserializedServerMsg.GetExtension(DiagnosticSessionToken2Extensions.DiagnosticSessionToken);

    actualToken.Should().Be(expectedToken);
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 18:54:53