2012-01-05 3 views
2

BinaryFormatter를 사용하여 다른 응용 프로그램에서 파일을 deserialize하고 있습니다. 이들은 기본 라이브러리를 공유하며 파일에서 직렬화 된 대부분의 형식이 알려져 있습니다..Net 바이너리 직렬화

그러나 일부 유형은 완전히 알려지지 않았으며 업데이트 할 수있는 일치 항목이 없습니다. 이러한 경우에 대해 직렬화를 제거 할 수 있기를 원합니다.

현재 SurrogateSelector 및 최근 버전의 네임 스페이스 변경의 영향을받는 형식을 업데이트하는 데 사용하는 SerializationBinder로 초기화 된 BinaryFormatter를 사용하고 있습니다.

var formatter = new BinaryFormatter 
{ 
    Context = streamingContext, 
    SurrogateSelector = ss, 
    Binder = new ProxiedRemappingSerializationBinder(), 
    FilterLevel = TypeFilterLevel.Low 
}; 

try 
{ 
    var deserializedObject = formatter.Deserialize(contentsStream); 
    ... 
} 

즉, 문제는 내부적으로, .NET 프레임 워크의 알려진 시도가 인터페이스의 배열에 값을 설정하는 때 발생하지만, 미지의 값 타입. 내가 얻을 예외 : "System.InvalidCastException :이 유형의 배열에 개체를 저장할 수 없습니다."

그래서 이러한 형식을 폐기하고 (물론 null을 남겨 둡니다) 역 직렬화 프로세스를 만들거나 SerializationBinder를 어떻게 든 연기하여이 예외를 방지 할 수있는 방법이 있습니까? 스택 추적 게다가 사전

** 수정 **

에서

덕분에 오류가 전형적인 InvalidCastException이있다. .NET Framework 내에서 BinaryFormatter, BinaryObjectReader 및 ObjectManager를 통해 디버깅했으며 배열의 실제 값을 인스턴스에 할당 할 때 픽스 업 단계에서 오류가 발생합니다. InternalSetValue의 Array.cs 516 줄에서 깨기 (& elemref, value); 예외가 발생하는 곳입니다.

나는 비 직렬화 시간의 일부 유형을 내 애플리케이션에서 알고있는 유형 (더 최신 버전의 유형)으로 변경하거나 더미 클래스로 변경하려고합니다. 예외가 발생하는 이유를 이해합니다. 기본적으로 인터페이스 배열에 호환되지 않는 개체 유형을 설정하려고합니다. 이 배열 인터페이스를 구현하지 않기 때문에 http://holistictendencies.wordpress.com/2009/11/16/creating-proxies-in-for-round-tripping-unknown-objects-in-c-server-apps/ 그래서, 실패 :

이 유형은 내가 동적으로 구현 유사 객체 정보를 유지하기 위해 생성 된 프록시 유형입니다. 엔진이이 사건들을 어떻게 든 버리길 바랄뿐입니다.

+0

C : 난 그냥 전달 된 것을 반환을 찾고

을 그럼 당신은 만들 때 귀하의 경우 BinaryFormatter 새 사용자 정의 바인더의 인스턴스에 바인더 속성을 설정 오류에 대한 자세한 정보를 얻으려면 catch 블록을 추가하십시오. – Paparazzi

+0

발람, 나는 탈 직렬화가 막을 것이고 그는 아무것도 얻을 수 없을 것이라고 생각한다. –

+0

MSDN을 읽을 필요없이'BinaryFormatter'의 'SurrogateSelector'와 Binder가 도움이되는 내용을 실제로 빨리 표현할 수 있습니까? –

답변

1

BinaryFormatter.Deserialize()에 대한 형식 정보가 없지만 해당 개체의 속성에서 일부 값을 가져오고 싶었던 비슷한 문제가있었습니다.

해당 개체를 deserialize 할 시간이 왔을 때 .NET은 SerializationException을 던져서 알 수없는 어셈블리 유형에 대해 불평했습니다.

나는 (serializable로 표시) 내가 필요로하는 특성을 가진 사용자 정의 클래스를 작성하여 그것을 해결하고 SerializationBinder에서 상속 다른 클래스 생성 :

public class MySerializationBinder : SerializationBinder 
{ 
    public override Type BindToType(string assemblyName, string typeName) 
    { 
     if (assemblyName.Contains("namespace I don't have") && typeName.Contains("type info I don't have")) 
       return typeof(MySubstitute); 
     return Type.GetType($"{typeName}, {assemblyName}"); 
    } 
} 

[Serializable] 
public class MySubstitute 
{ 
    public string Name { get; set; } 
    public string Title { get; set; } 
} 

공지 사항을 어떻게 내가 형식이 아닌 경우 .

using (FileStream fs = new FileStream(openFileDialog1.FileName, FileMode.Open)) 
{ 
     BinaryFormatter bf = new BinaryFormatter() 
     { 
      Binder = new MySerializationBinder() 
     };      
     mySubstitute = (MySubstitute)bf.Deserialize(fs);   
     fs.Close(); 
} 
관련 문제