У меня есть рабочий 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 from 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
. Пробовал как с ним, так и без ...