Google Protobuf - отсутствует дескриптор для реестра типов

У меня есть некоторый Google Protobuf json с полем «@type», значение которого является URI, который сообщит кому-то тип сообщения Protobuf, например. "@type": "type.googleapis.com/llcore.ModemDataAtlas". Насколько я понимаю, эти строки json должны быть сначала сериализованы в тип Any. всякий раз, когда я это делаю, я получаю следующую ошибку:

System.InvalidOperationException: Type registry has no descriptor for type name ''llcore.ModemMessage'

Вот мой код:

string jsonString = "";
string jsonPath = @"C:\Users\user\Documents\TestRepos\ExampleProto\protoType.json";
using (StreamReader reader = new StreamReader(jsonPath))
{
    jsonString = reader.ReadToEnd();
}

Any anyProto = Any.Parser.ParseJson(msg); // Exception occurs here

Кто-нибудь знает, как правильно десериализоваться в класс Protobuf Any? Как создать реестр типов и добавить для него дескриптор?


person Roka545    schedule 24.08.2019    source источник


Ответы (1)


Сначала позвольте мне объяснить, почему вы не можете просто разобрать/сериализовать произвольный JSON в Any (или наоборот). Any сам имеет 2 поля:

  • typeUrl - В вашем случае "type.googleapis.com/llcore.ModemDataAtlas"
  • value - Фактический контент, закодированный как двоичный protobuf

Двоичный protobuf кодирует каждое поле как пару ключа и содержимого, думайте об этом как о карте. Ключ — это не имя поля, а номер, присвоенный полю в прото-определении.

Объект JSON также является картой, но он использует имя поля в качестве индекса. Таким образом, без какой-либо информации о типе (дескриптора) анализатор JSON не знал бы, как сопоставить именованное поле объекта JSON с его двоично-кодированной версией, которая идентифицируется только числом.

Просто чтобы было ясно: вы не можете анализировать/сериализовать неизвестные типы, которые закодированы как Any! Ваше приложение должно знать о них либо путем статической компиляции в него дескрипторов, либо путем поиска дескрипторов типов во время выполнения. В основном это точка TypeRegistry, чтобы позволить вам загружать дескрипторы во время выполнения, но вы должны предоставить эту инфраструктуру поиска типов самостоятельно.

Чтобы это работало в вашем случае, ваше приложение должно знать о типах, которые упакованы в файле Any. Затем вы можете создать TypeRegistry и передать его конструктору JsonParser. Я не C# разработчик, но что-то вроде:

var registry = TypeRegistry.FromMessages(MyMessage.Descriptor);
var parser = new JsonParser(new JsonParser.Settings(20, registry));
var message =  parser.Parse<Any>(payload);
person Maik    schedule 24.08.2019