2013-04-20 2 views
2

이렇게하면 런타임시 직렬화 예외가 발생합니다. 이 작업을 수행하는 가장 좋은 방법을 테스트하는 데모 프로젝트입니다. 나는 main 메소드와 직렬화하려는 클래스를 포함했다.연재시 어떤 실수를 했습니까?

무시 : 정말 자세한 내용을 추가 할 수 없습니다. 문제를 설명하고 코드를 첨부했습니다.이 "자세한 내용을 추가하십시오."라는 것은 지금까지 가장 바보 같은 것입니다. 내가 이미 게시하게 해 줘.

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, 문화 = 중립 버전 = 1.0.0.0는, PublicKeyToken = null이' 로 직렬화 표시되지 않습니다.

+1

@walther 'SerializationDemo, Version = 1.0.0.0, Culture = neutral, PublicKeyToken = null'어셈블리의 'SerializationDemo.Data'형식이 직렬화 가능으로 표시되어 있지 않습니다. – Innkeeper

+0

기다려 ... 그 말은, [] 속성도 필요합니까? 인터페이스에서 충분히 파생되지 않았습니까? – Innkeeper

+1

'[Serializable]'은 당신이 필요로하는 것입니다 – IAbstract

답변

4

대답은 예외 메시지에서 당신에게 주어집니다 :

유형 총회에서 'SerializationDemo.Data' 'SerializationDemo, 버전 = 1.0.0.0이, 문화, PublicKeyToken = null이 중립 ='입니다 은 으로 serializable로 표시되어 있지 않습니다.

클래스를 Serializable 속성으로 표시해야합니다. (때문에 지역 변수 이름 toSend, toReceive 에 추론) 네트워크 아래로 객체를 전송하는가는 것처럼 보이는 상황에서

[Serializable()] class Data : ISerializable 

. 예를 들어 클라이언트 - 서버 모델을 사용하는 경우 서버 소프트웨어에서 직렬화되어 전송 된 객체는 기본적으로 클라이언트 소프트웨어에서 직렬화 할 수 없습니다.

이진 직렬화의 기본 특성은 유형 시스템 충실도를 유지한다는 것입니다. 유형 시스템 충실도는 유형 정보가 직렬화 프로세스에서 손실되지 않는다는 것을 나타냅니다. 즉, 객체를 직렬화 할 때 is는 데이터 스트림에 기록되는 "객체 상태"일뿐만 아니라 클래스 및 포함 어셈블리의 이름입니다. 데이터를 deserialize하려고하는 어셈블리에서 Data 클래스를 정의하더라도 deserializer가 Program1.Namespace.Data이 아닌 Program2.Namespace.Data을 찾을 것이기 때문에 deserialize 메서드가 실패합니다 (예외가 발생 함). 이 문제를 해결하려면 상호 어셈블리 (클래스 라이브러리)에서 데이터 메시지를 정의하거나 기본적으로 deserialize 메서드를 속여 동일한 어셈블리에 있다고 생각하도록 SerializationBinder을 정의하면됩니다.

+0

이것은 내가 생각했던 것보다 더 복잡하다. 이것은 단지 더미 테스트 프로그램이지만, 나의 의도는 TCP 연결을 통해 그것을 보낸다는 것이다. DLL에서 클래스를 정의하고 서버와 클라이언트 프로젝트 모두에서 링크하는 것이 좋은 전략입니까? 컨텍스트 멀티 체스 애플 리케이션이며, 보드 인스턴스를 전송하고 싶습니다. – Innkeeper

+0

@Innkeeper 독자적인 어셈블리에서 메시지를 정의하는 것이 좋은 생각입니다. 직렬화 프로세스가 쉬우 며 클래스를 복사하여 붙여 넣을 필요가 없으며 매번 어셈블리에 메시지 식별자를 열거 할 수도 있기 때문입니다 새 메시지를 추가합니다. 유일한 단점은 응용 프로그램이 DLL에 종속되어 더 이상 독립 실행할 수 없다는 것입니다. –

관련 문제