Protobuf-net Serialize в строку и сохранить в базе данных, а затем де-Serialize - PullRequest
19 голосов
/ 02 августа 2011

Я хотел бы сериализовать / десериализовать объект, используя строку. Просто чтобы заметить, когда я сериализую / десериализовать в файл все работает нормально Я пытаюсь получить строку, чтобы я мог сохранить ее в базе данных, а затем вытащить ее для десериализации.

Вот код, который работает:

MemoryStream msTest = new MemoryStream();
Serializer.Serialize(msTest, registrationBlocks);
msTest.Position = 0;
List<RVRegistrationBlock> CopiedBlocks = new List<RVRegistrationBlock>();
CopiedBlocks = Serializer.Deserialize<List<RVRegistrationBlock>>(msTest);

Объект "CopiedBlocks" - это тот же список, который был в "registrationBlocks". Отлично работает, все сериализовано / десериализовано. Я держу все в потоках здесь.

Вот код, который не работает, когда я пытаюсь задействовать строку:

MemoryStream msTestString = new MemoryStream();
Serializer.Serialize(msTestString, registrationBlocks);


msTestString.Position = 0;
StreamReader srRegBlock = new StreamReader(msTestString);

byte[] bytedata64 = System.Text.Encoding.Default.GetBytes(srRegBlock.ReadToEnd());

string stringBase64 = Convert.ToBase64String(bytedata64);

byte[] byteAfter64 = Convert.FromBase64String(stringBase64);
MemoryStream afterStream = new MemoryStream(byteAfter64);


List<RVRegistrationBlock> CopiedBlocksString = new List<RVRegistrationBlock>();
CopiedBlocksString = Serializer.Deserialize<List<RVRegistrationBlock>>(afterStream);

В последней строке, когда идет десериализация, я получаю исключение: было сгенерировано исключение типа ProtoBuf.ProtoException. Я не могу углубиться в это, внутреннее исключение - ноль. Я не могу понять, почему он это делает.

Я определенно сузил это до того факта, что когда я вовлекаю строку, она становится бесполезной. Я храню строку в базе данных в nvarchar (max), поэтому я хочу эту строку.

Любая помощь будет очень признательна!

Ответы [ 2 ]

24 голосов
/ 02 августа 2011

Я немного растерялся из-за использования StreamReader в этом контексте, мне показалось бы, что вы могли бы опустить это и сделать что-то вроде ниже, чтобы убедиться, что однонаправленное кодирование не происходит ..

MemoryStream msTestString = new MemoryStream();
Serializer.Serialize(msTestString, registrationBlocks);

string stringBase64 = Convert.ToBase64String(msTestString.ToArray());

byte[] byteAfter64 = Convert.FromBase64String(stringBase64);
MemoryStream afterStream = new MemoryStream(byteAfter64);

List<RVRegistrationBlock> CopiedBlocksString = new List<RVRegistrationBlock>();
CopiedBlocksString = Serializer.Deserialize<List<RVRegistrationBlock>>(afterStream);
2 голосов
/ 18 апреля 2017

На основании ответа и комментария я использую это:

        internal static string SerializeToString_PB<T>(this T obj)
        {
            using (MemoryStream ms = new MemoryStream())
            {
                ProtoBuf.Serializer.Serialize(ms, obj);
                return Convert.ToBase64String(ms.GetBuffer(), 0, (int)ms.Length);
            }
        }
        internal static T DeserializeFromString_PB<T>(this string txt)
        {
            byte[] arr = Convert.FromBase64String(txt);
            using (MemoryStream ms = new MemoryStream(arr))
                return ProtoBuf.Serializer.Deserialize<T>(ms);
        }
...