تسلسل الحقول غير المطلوبة في protobuf-net
-
25-09-2019 - |
سؤال
لديّ عميل 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 طلبًا سيئًا من Google). عندما أقوم بتعيين صريح appId
ل null
في عميل Java ، كل شيء يعمل ، ولكن فقط بسبب hasAppId
يتم ضبطه على خطأ (أنا غير متأكد من كيفية تأثير ذلك على التسلسل).
في عميل C# ، أحصل دائمًا على 403 ردًا. لا أرى أي منطق وراء التمييز بين عدم تعيين قيمة ، وتعيين القيمة الافتراضية ، ويبدو أن هذا يحدث فرقًا في عميل Java. نظرًا لأن الإخراج دائمًا ما يكون دفقًا ثنائيًا ، لست متأكدًا مما إذا كانت رسائل Java الناجحة يتم تسلسلها بسلسلة فارغة ، أو لم يتم تسلسلها على الإطلاق.
في عميل C# ، حاولت الإعداد IsRequired
إلى صحيح على 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
يفعل. لقد جربت مع ذلك وبدونه ...
المحلول
يبدو أننا نريد إجباره على استبعاده ؛ لأول شيء يجب تجربته ، يمكنك محاولة استخدام خيار "اكتشاف" في جيل التعليمات البرمجية. هذا ممكن من IDE وخط الأوامر ، ولكن بشكل مختلف (اسمحوا لي أن أعرف ما الذي تستخدمه وسأضيف المزيد).
خيار آخر مشابه هو إضافة (في فئة جزئية) أ bool {memberName}Specified {get;set;}
. هناك تقرير مفتوح موجود عن غرابة تتضمن سلاسل فارغة افتراضية ، وأنا أنظر إليها.