Проблема с сериализацией

2

У меня проблема с сериализацией. Я хочу преобразовать объект в строку и наоборот. У меня есть два метода утилиты:

public
static byte[] Serialize(Object o)
{
   MemoryStream ms = new MemoryStream();
   BinaryFormatter bf1 = new BinaryFormatter();
   bf1.Serialize(ms, o);
   byte[] buffer = ms.ToArray();
   //string retStr = Convert.ToBase64String(buffer);
   return buffer;
}

public static object Deserialize(byte[] TheByteArray)
{
   //byte[] TheByteArray = Convert.FromBase64String(ParamStr);
   MemoryStream ms = new MemoryStream(TheByteArray);
   BinaryFormatter bf1 = new BinaryFormatter();
   ms.Position = 0;
   return bf1.Deserialize(ms);
}

Мой тестовый код:

Student obj = new Student ();
obj.UserName = "Admin";
obj.Password = "Password";
obj.lessonIds = new int[] { 1, 2, 3, 4, 5 };
obj.lessonNames= new string[] { "Spanish", "Maths" };
obj.Id= 43;
byte[] retByteArray = Crypto.Serialize(obj);

Student objNew = new Student ();
objNew = (Student )Crypto.Deserialize(retByteArray);

этот код не работает. Сообщение об ошибке: Исключение было выбрано целевым объектом вызова. Конец потока, встреченный до разбора, был завершен.

Конец моей основной цели - преобразовать объект в строку, но я даже не могу преобразовать его в массив байтов

  • 0
    На что же ссылается Cryto?
  • 0
    Это не ошибка, но вам не нужно Student objNew = new Student (); перед вызовом десериализации. Вы просто создаете объект, а затем заменяете его другим.
Показать ещё 1 комментарий
Теги:
serialization

3 ответа

1

Я только что попробовал оригинальный код, и он отлично работает, однако вам нужно убедиться, что определение класса ученика помечено как [Serializable]

[Serializable]
public class Student
{
    public string UserName;
    public string Password;
    public int[] lessonIds;
    public string[] lessonNames;
    public int Id;
    public Student() { }
}
0

Этот код отлично работает для меня (я просто добавил отсутствующий класс Student. Является ли этот код действительным для вашего реального кода. В частности, обработка буфера (возможно, файл IO) была бы моим первым подозрением. 't в коде, который вы отправили... он отлично работает.

Как в стороне... BinaryFormatter может быть хрупким, особенно в разных версиях - вы можете рассмотреть альтернативные сериализаторы. Если вам интересно, запросите дополнительную информацию.

Здесь он запускается:

using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
using System;
static class Crypto
{
    static byte[] Serialize(object o)
    {
        MemoryStream ms = new MemoryStream();
        BinaryFormatter bf1 = new BinaryFormatter();
        bf1.Serialize(ms, o);
        byte[] buffer = ms.ToArray();
        //string retStr = Convert.ToBase64String(buffer);
        return buffer;
    }

    public static object Deserialize(byte[] TheByteArray)
    {
        //byte[] TheByteArray = Convert.FromBase64String(ParamStr);
        MemoryStream ms = new MemoryStream(TheByteArray);
        BinaryFormatter bf1 = new BinaryFormatter();
        ms.Position = 0;
        return bf1.Deserialize(ms);
    }
    [Serializable]
    class Student
    {
        public string UserName { get; set; }
        public string Password { get; set; }
        public int[] LessonIds { get; set; }
        public string[] LessonNames { get; set; }
        public int Id { get; set; }
    }
    static void Main()
    {
        Student obj = new Student();
        obj.UserName = "Admin";
        obj.Password = "Password";
        obj.LessonIds = new int[] { 1, 2, 3, 4, 5 };
        obj.LessonNames = new string[] { "Spanish", "Maths" };
        obj.Id = 43;
        byte[] retByteArray = Crypto.Serialize(obj);

        Student objNew = (Student)Crypto.Deserialize(retByteArray);
    }
}
  • 0
    Для информации я просто провел его через protobuf-net для сравнения: BinaryFormatter = 363 байта; protobuf-net = 45 байт ...
  • 0
    Спасибо всем. Я нашел свою ошибку. Мой ученический класс реализует интерфейс ISerializable; когда я удаляю это, это работает. Но я не понял проблему с интерфейсом.
0

Возможно, вы страдаете от состояния гонки, потому что вы не закрываете поток памяти или ваш форматировщик, когда закончите сериализацию.

Попробуйте следующее:

public
static byte[] Serialize(Object o)
{
   using (MemoryStream ms = new MemoryStream())
   {
       BinaryFormatter bf1 = new BinaryFormatter();
       bf1.Serialize(ms, o);
       byte[] buffer = ms.ToArray();
       //string retStr = Convert.ToBase64String(buffer);
   }
   return buffer;
}

public static object Deserialize(byte[] TheByteArray)
{
   //byte[] TheByteArray = Convert.FromBase64String(ParamStr);
   using (MemoryStream ms = new MemoryStream(TheByteArray))
   {
       BinaryFormatter bf1 = new BinaryFormatter();
       ms.Position = 0;
       var result = bf1.Deserialize(ms);
   }
   return result;
}
  • 1
    Это не должно иметь никакого значения в этом случае ...
  • 0
    @ Марк, ты так не думаешь? Почему?
Показать ещё 7 комментариев

Ещё вопросы

Сообщество Overcoder
Наверх
Меню