Десериализация ByteString в объект с использованием C# Google.Protobuf - PullRequest
2 голосов
/ 03 марта 2020

Итак, у меня есть сообщение gRP C, поступающее из другого сервиса (написанное на другом языке программирования). Вот мини-версия этого объекта (очевидно, реальная генерируется protobuf)

public class Message
{
    public string Topic { get; set; }
    public string Identifier { get; set; }
    public Google.Protobuf.ByteString Msg { get; set; }
}

Моя проблема заключается в том, что ByteString должен быть десериализован в другой объект (также определенный в файле protobuf), но когда я пытаюсь десериализовать поле Msg, но получаю эту ошибку:

Протокол содержит тег с недопустимым типом провода.

и трассировку стека

в Google.Protobuf.UnknownFieldSet.MergeFieldFrom (вход CodedInputStream) в Google.Protobuf.UnknownFieldSet.MergeGroupFrom (вход CodedInputStream) в Google.Protobuf.CodedInputStream.ReadGroup (в неизвестном месте). UnknownFieldSet.MergeFieldFrom (вход CodedInputStream) в Google.Protobuf.UnknownFieldSet.MergeFieldFrom (UnknownFieldSet unknownFields, вход CodedInputStream) в сообщениях. NewRecorderTester \ Infra.App DataManager \ Model \ Protos \ Pubsub \ messages.pb.cs: строка 3259 в ClusterRecordersModule.RecordersViewModel.OnNewMessage (Сообщение сообщения) в C: \ Users \ iliaar \ go \ src \ RecorderApp \ testers \ NewRecorderTester \Modelsor RecordersViewModel.cs: строка 154

Я попытался вызвать несколько методов нового объекта, и все не удалось, например, я попытался использовать существующий экземпляр и объединить как:

innerMessageObject.MergeFrom(message.Msg.CreateCodedInput());

или используя синтаксический анализатор stati c, например:

InnerMessageObject.Parser.ParseFrom(message.Msg.ToByteArray());

, и все они потерпели неудачу с одинаковой ошибкой, и трассировка стека в конечном итоге сходится в том же месте в библиотеке Google.Protobuf. моя версия библиотеки 8.1.0, и я также попытался снизить ее до версии 6

, я был бы очень признателен за помощь. Спасибо

Редактировать: объект innerMessage структурирован следующим образом:

public class InnerMessageObject
{
    public string ConfigID { get; set; }
    public bool Storage { get; set; }
    public bool Signal { get; set; }
    public string StorageTransition { get; set; }
    public string SignalTransition { get; set; }
}

также, преобразование в шестнадцатеричный результат приводит к следующему (действительному) выводу

63-6F-6E-66-69-67-5F-69-64-3A-20-37-32-30-62-66-65-34-39-2D-64-62-32-39-2D-34-35-38-33-2D-39-66-65-31-2D-65-30-32-30-37-33-32-37-39-37-39-34-0A-73-74-6F-72-61-67-65-3A-20-66-61-6C-73-65-0A-73-69-67-6E-61-6C-3A-20-66-61-6C-73-65-0A-73-74-6F-72-61-67-65-5F-74-72-61-6E-73-69-74-69-6F-6E-3A-20-22-32-30-32-30-2D-30-33-2D-30-33-54-31-32-3A-32-36-3A-34-31-2E-33-32-37-34-30-34-33-5A-22-0A-73-69-67-6E-61-6C-5F-74-72-61-6E-73-69-74-69-6F-6E-3A-20-22-32-30-32-30-2D-30-33-2D-30-33-54-31-32-3A-32-36-3A-34-31-2E-33-32-37-34-30-33-32-33-31-5A-22-0A

далее покрытие байтового массива в строку приводит к строковому представлению объекта с правильными данными

var ba = pubsubMessage.Msg.ToByteArray();
return Encoding.UTF8.GetString(ba);

config_id: 720bfe49-db29-4583-9fe1-e02073279794 storage: false сигнал: false storage_transition: " 2020-03-03T12: 29: 59.531473957Z "signal_transition:" 2020-03-03T12: 29: 59.531473589Z "

1 Ответ

2 голосов
/ 03 марта 2020

Ваша полезная нагрузка не является протобуф . Если мы попробуем через этот валидатор , мы увидим:

63 = поле 12, введите StartGroup

error: Invalid wire-type; обычно это означает, что вы перезаписали файл без усечения или установки длины; см. Используя Protobuf- net, я неожиданно получил исключение о неизвестном проводном типе

, поэтому давайте посмотрим на первые два байта, как если бы они были protobuf - декодером говорит нам, что означает 0x63; следующий байт 0x6F должен быть заголовком поля («тег»); в двоичном виде это 01101111, который будет «полем 13, проводного типа 7»; там нет провода типа 7 в протобуфе . Так; декодер правильный: полезная нагрузка недействительна.

Но не все потеряно!

Если мы возьмем предположение из всех этих значений 0x6 *, что это может быть ASCII или UTF8, и декодируем Таким образом, мы получаем:

config_id: 720bfe49-db29-4583-9fe1-e02073279794
storage: false
signal: false
storage_transition: "2020-03-03T12:26:41.3274043Z"
signal_transition: "2020-03-03T12:26:41.327403231Z"

, который, по-видимому, представляет собой ваши данные в каком-то грубом формате на основе строк. Но: не протобуф.

...