Protobuf-net Сериализовать в String и сохранить в базе данных Затем De Serialize
Я хотел бы сериализовать/де-сериализовать объект с помощью строки. Просто отметить, когда я сериализую/де-сериализую в файл, все работает нормально. То, что я пытаюсь сделать, это получить строку, чтобы я мог сохранить ее в базе данных, а затем вытащить ее позже для де-сериализации.
Вот код, который работает:
MemoryStream msTest = new MemoryStream();
Serializer.Serialize(msTest, registrationBlocks);
msTest.Position = 0;
List<RVRegistrationBlock> CopiedBlocks = new List<RVRegistrationBlock>();
CopiedBlocks = Serializer.Deserialize<List<RVRegistrationBlock>>(msTest);
Объект "Скопированные блоки" - это тот же список, что и в "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. Я не могу просверлить его, внутреннее исключение - null. Я не могу понять, почему он это делает.
Я определенно сузил его до того факта, что когда я получаю строку, она идет с haywire. Я сохраняю строку в базе данных в nvarchar (max), поэтому я хочу строку.
Любая помощь будет оценена по достоинству!
Ответы
Ответ 1
Я немного потерял использование 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
Основываясь на ответе и комментарии, я использую следующие:
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);
}