2013-04-20 1 views
2

Это приводит к исключению сериализации во время выполнения. Это просто демонстрационный проект, чтобы проверить лучший способ сделать это. Я включил основной метод и класс, которые я пытаюсь выполнить сериализацией.Какую ошибку я делаю при сериализации?

Игнорировать: я действительно не могу добавить больше деталей, я описал проблему, приложил код, это «пожалуйста, добавьте больше деталей», вещь - самая глупая вещь. Позвольте мне опубликовать его уже.

Data toSend = new Data(); 
toSend.Output(); 

///SERIALIZE 

BinaryFormatter formatter = new BinaryFormatter(); 
Stream streamOut = File.OpenWrite("file"); 
formatter.Serialize(streamOut, toSend); 
streamOut.Close(); 


Console.WriteLine("----------------------------"); 
///DESERIALIZE 

Stream streamIn = File.OpenRead("file"); 
Object received = formatter.Deserialize(streamIn); 
Data toReceive = (Data)received; 
toReceive.Output(); 

class Data : ISerializable 
{ 
    int integerData; 
    string stringData; 
    bool booleanData; 
    int shouldnotbeserialized; 

    public Data() 
    { 
     integerData = 1; 
     stringData = "Hello"; 
     booleanData = true; 
     shouldnotbeserialized = 55; 
    } 

    //To deserialize 
    public Data(SerializationInfo info, StreamingContext context) 
    { 
     integerData = info.GetInt32("theint"); 
     stringData = info.GetString("thestring"); 
     booleanData = info.GetBoolean("thebool"); 
    } 

    public void Output() 
    { 
     Console.WriteLine(integerData); 
     Console.WriteLine(stringData); 
     Console.WriteLine(booleanData); 
     Console.WriteLine(shouldnotbeserialized); 
    } 

    //Implemented method to serialize 
    public void GetObjectData(SerializationInfo info, StreamingContext context) 
    { 
     info.AddValue("thestring", stringData); 
     info.AddValue("theint", integerData); 
     info.AddValue("thebool", booleanData); 
    } 
} 

Сообщение об исключении:

Тип 'SerializationDemo.Data' в 'Ассамблеи SerializationDemo, Version = 1.0.0.0, культура = нейтральной, PublicKeyToken = нуль' не отмечен как сериализуемый.

+1

@walther Тип 'SerializationDemo.Data' в Assembly 'SerializationDemo, Version = 1.0.0.0, Culture = neutral, PublicKeyToken = null' не помечен как сериализуемый. – Innkeeper

+0

Подождите ... Означает ли это, мне также нужен атрибут []? Не получается ли из интерфейса достаточно? – Innkeeper

+1

'[Serializable]' то, что вам нужно – IAbstract

ответ

4

Ответ дан вам в сообщении исключения:

Тип 'SerializationDemo.Data' в 'Ассамблеи SerializationDemo, Version = 1.0.0.0, культура = нейтральной, PublicKeyToken = нуль' является не указано как сериализуемое.

Необходимо указать свой класс атрибутом Serializable.

[Serializable()] 
class Data : ISerializable 

Из контекста кажется, как вы собираетесь передавать объект вниз сети (выведенный из-за имен локальных переменных ToSend, toReceive). Вы должны знать, что если вы, например, используете модель клиент-сервер, объект, сериализованный и отправленный с серверного программного обеспечения, по умолчанию не будет десериализуем из клиентского программного обеспечения.

Это связано с тем, что фундаментальная характеристика двоичной сериализации заключается в том, что она сохраняет верность системы типов. Точность системы типа означает, что информация о типе не теряется в процессе сериализации. Это означает, что когда вы сериализуете объект, это не только «состояние объекта», записанное в поток данных, но также имя класса и содержащейся сборки. Даже если вы определили класс Data в сборке, который будет десериализовать данные, метод десериализации будет терпеть неудачу (выбросить исключение), потому что десериализатор будет искать тип Program1.Namespace.Data не Program2.Namespace.Data. Чтобы исправить это, вы можете определить свои сообщения данных во взаимной сборке (библиотеке классов) или путем определения SerializationBinder, что позволит вам в основном обмануть метод десериализации, считая, что вы все еще в одной и той же сборке.

+0

Это сложнее, чем я думал тогда, это всего лишь фиктивная тестовая программа, но да, я собирался отправить ее через tcp-соединение. Так что это хорошая стратегия для определения класса в DLL и связать его как с серверами, так и с клиентскими проектами? Контекст - это многопользовательское шахматное приложение, и я хочу передать экземпляр платы. – Innkeeper

+0

@ Innkeeper Я считаю, что определение ваших сообщений в их собственной сборке является хорошей идеей, потому что это упрощает процесс сериализации, а также означает, что вам не нужно копировать и вставлять класс и, возможно, перечислять идентификаторы сообщений в сборках каждый раз вы добавляете новое сообщение. Единственная нижняя сторона заключается в том, что ваше приложение будет зависеть от вашей DLL и больше не будет автономным исполняемым файлом. –

Смежные вопросы