У меня есть работающий Java-клиент, который связывается с Google через сериализованные сообщения ProtoBuf. В настоящее время я пытаюсь перевести этого клиента на C #.
У меня есть файл .proto
, где параметр appId
является необязательной строкой. Его значение по умолчанию в представлении C #, генерируемое библиотекой protobuf-net, является пустой строкой, как и в представлении java того же файла.
message AppsRequest {
optional AppType appType = 1;
optional string query = 2;
optional string categoryId = 3;
optional string appId = 4;
optional bool withExtendedInfo = 6;
}
Я обнаружил, что когда я явно устанавливаю appId
в ""
в клиенте java, клиент перестает работать (403 Bad Request от Google). Когда я явно устанавливаю appId
в null
в клиенте java, все работает, но только потому, что для hasAppId
задано значение false (я не знаю, как это повлияет на сериализацию).
В клиенте C # я всегда получаю 403 ответа. Я не вижу никакой логики за различием между не установкой значения и установкой значения по умолчанию, которое, кажется, имеет все значение в Java-клиенте. Поскольку выходные данные всегда являются двоичным потоком, я не уверен, что успешные сообщения Java сериализуются с пустой строкой или не сериализуются вообще.
В клиенте C # я попытался установить IsRequired
в значение true для атрибута ProtoMember
, чтобы заставить их сериализоваться, и я попытался установить значение по умолчанию в null и явно установить ""
, так что я совершенно уверен, что попробовал некоторую конфигурацию, где значение сериализуется. Я также поиграл с ProtoBuf.ProtoIgnore
и в какой-то момент вообще удалил параметр appId
, но мне не удалось избежать 403 ошибок в C #.
Я попытался вручную скопировать сериализованную строку из Java, и это решило мои проблемы, поэтому я уверен, что остальная часть HTTP-запроса работает, и ошибка может быть отслежена для сериализованного объекта.
Моя сериализация просто так:
var clone = ProtoBuf.Serializer.DeepClone(request);
MemoryStream ms = new MemoryStream(2000);
ProtoBuf.Serializer.Serialize(ms, clone);
var bytearr = ms.ToArray();
string encodedData = Convert.ToBase64String(bytearr);
Я признаю, что не совсем уверен в том, что делает DeepClone
. Я пробовал как с, так и без него ...