Как (base64) кодировать протобуф как строку для REST - PullRequest
1 голос
/ 14 февраля 2020

Я хочу использовать Protobuf объекты в REST сервисе.

  • Мне нужно десериализовать входящую строку из base64 в объект Protobuf (IMessage)
  • Мне нужно сериализовать исходящий объект Protobuf в строку base64

    Какой самый простой способ сделать это?

Ответы [ 2 ]

1 голос
/ 14 февраля 2020

Короткая версия

Сериализация:

using Google.Protobuf; // don't forget: .ToByteString() is an extension method
string encoded = proto.ToByteString().ToBase64();
// Output: ChAKDEdsb2JhbCBzdGF0ZRAB

Десериализация:

MyProtobufClass myC = new MyProtobufClass();
myC .MergeFrom(ByteString.FromBase64(messageBase64));

Полная версия: класс помощника

public static class ProtobufHelper
{
    /// <summary>
    /// Transform base64 string message to protobuf IMessage object
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="messageBase64"></param>
    /// <returns></returns>
    public static T DeserializeProtobuf<T>(string messageBase64) where T: IMessage, new()
    {
        T result = new T();
        if (!String.IsNullOrWhiteSpace(messageBase64))
        {
            if (messageBase64.StartsWith("\"") && && messageBase64.Length > 2)
                messageBase64 = messageBase64.Substring(1, messageBase64.Length - 2);
            result.MergeFrom(ByteString.FromBase64(messageBase64));
        }
        return (result);
    }

    /// <summary>
    ///  Transform protobuf IMessage object to base64 string message
    /// </summary>
    /// <param name="message"></param>
    /// <returns></returns>
    public static string SerializeProtobuf(IMessage message)
    {
        return (message.ToByteString().ToBase64());
    }
}

Использование в REST-сервисе

  public class MyCustomController : ApiController
  {

        /// <summary>
        /// REST Get method
        /// </summary>
        /// <param name="requestPayload">String containing a base64 serialized MyProtobufRequest object</param>
        /// <returns>String containing a base64 serialized MyProtobufReply object</returns>
        public string Get(string requestPayload)
        {
            var requestObj = ProtobufHelper.DeserializeProtobuf<MyProtobufRequest>(requestPayload);
            return (ProtobufHelper.SerializeProtobuf(GetHandler(requestObj)));
        }

        private MyProtobufReply GetHandler(MyProtobufRequestrequest request)
        {
           // Type your code here
           return new MyProtobufReply();
        }                
  }
0 голосов
/ 20 февраля 2020

На мой взгляд, совершенно неправильно использовать прото-сообщения, сериализованные в строку, и наоборот. Это совершенно противоположно проекту protobuf. * ​​1001 *

Идеальным решением является установка типа контента в поток октетов (двоичный) и использование методов toByteArray() и parseFrom({bytearray}) для достижения максимальной производительности. Таким образом, ваши данные будут занимать очень мало места в сети, и вы получите лучшую производительность сети.

С другой стороны, лучшим решением может быть использование потоковой передачи везде и потоковой передачи протобайтов с помощью метода. protoObj.writeDelimitedTo({an http output stream}) и с {protoDefClass}.parseDelimitedFrom({an http input stream})

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...