2010-07-14 30 views
12

Tôi đang tìm kiếm thông tin chi tiết về cách thiết lập nền tảng thời gian chạy để hiển thị loại nguồn của lỗi Microsoft deserialization .Net nhị phân..Net Binary Deserialization Phát hiện lỗi/pháp y cho nền tảng thời gian chạy

Khi sử dụng BinaryFormatter.Deserialize(StreamingContextStates.CrossMachine) và một trong các loại không tồn tại trong các tệp nhị phân hiện tại; thay vì ném một lỗi, .Net chèn đối tượng [TypeLoadExceptionHolder]. Riêng đối với các bộ sưu tập, điều này không gây ra vấn đề gì ngay lập tức.

Sau đó, khi bộ sưu tập được sắp xếp để truyền giữa các tầng ứng dụng; nền tảng nhận được một 'thất bại tuần tự hóa' vì không thể tuần tự hóa [TypeLoadExceptionHolder]. Vì vậy, lỗi kết quả là vô ích khi thực sự cung cấp các manh mối về loại nguồn gây ra sự cố. Bây giờ việc săn (thời gian hút) là để xem nhà phát triển (trong số hàng trăm) đã thêm một loại mới vào một nền tảng triệu dòng.

Sự cố này xảy ra với một số tần suất do luồng tuần tự hóa được sử dụng để hỗ trợ nền tảng sessioncache. Mã được triển khai khá thường xuyên và theo kiểu tăng dần. Các yêu cầu trang của khách hàng có thể bị trả lại giữa các phiên bản cũ và mới của codebase trong cửa sổ triển khai. Sự giới thiệu bất cẩn của một kiểu mới sẽ làm cho các yêu cầu trang trên phiên bản cũ bị thổi phồng.

Bất kỳ suy nghĩ nào về việc cung cấp lỗi/bẫy thời gian chạy phong phú sẽ được đánh giá cao.


(SerializationException) 
Type 'System.Runtime.Serialization.TypeLoadExceptionHolder' in Assembly 'mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' is not marked as serializable. 
- at System.Runtime.Serialization.FormatterServices.InternalGetSerializableMembers(RuntimeType type) 
- at System.Runtime.Serialization.FormatterServices.GetSerializableMembers(Type type, StreamingContext context) 
- at System.Runtime.Serialization.Formatters.Binary.WriteObjectInfo.InitMemberInfo() 
- at System.Runtime.Serialization.Formatters.Binary.WriteObjectInfo.InitSerialize(Object obj, ISurrogateSelector surrogateSelector, StreamingContext context, SerObjectInfoInit serObjectInfoInit, IFormatterConverter converter, ObjectWriter objectWriter) 
- at System.Runtime.Serialization.Formatters.Binary.WriteObjectInfo.Serialize(Object obj, ISurrogateSelector surrogateSelector, StreamingContext context, SerObjectInfoInit serObjectInfoInit, IFormatterConverter converter, ObjectWriter objectWriter) 
- at System.Runtime.Serialization.Formatters.Binary.ObjectWriter.Write(WriteObjectInfo objectInfo, NameInfo memberNameInfo, NameInfo typeNameInfo) 
- at System.Runtime.Serialization.Formatters.Binary.ObjectWriter.Serialize(Object graph, Header[] inHeaders, __BinaryWriter serWriter, Boolean fCheck) 
- at System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Serialize(Stream serializationStream, Object graph, Header[] headers, Boolean fCheck) 

Trả lời

4

Vâng, một cách tiếp cận bạn có thể thực hiện là sử dụng một tùy chỉnh SerializationBinder đó sẽ ghi đè BindToType và kiểm tra các loại tên trong deserialization.

Tùy thuộc vào những gì bạn muốn đạt được, khi bạn xác định một loại không rõ bạn có thể một trong hai:

  • Nâng cao một ngoại lệ (bi quan): Nắm bắt vấn đề này từ rất sớm và có thể dễ dàng nhận diện các loại với một thông báo tùy chỉnh hoặc ngoại lệ.

  • Đăng nhập tên loại (Optimistic): Nếu có trường hợp không rõ loại OK, ghi nhật ký sẽ cung cấp chi tiết cần thiết để chẩn đoán ngoại lệ nếu chúng xảy ra sau này trong quá trình tuần tự hóa.

Bạn cũng có thể chọn cách tiếp cận khác tùy thuộc vào đặc điểm của tên loại (tức là nếu loại dường như là một phần của ứng dụng hoặc một phần của thư viện bên thứ 3).

Ví dụ TypeLoadExceptionHolder được tạo trong quá trình deserialization có chứa thành viên không công khai TypeName có chứa tên của loại không thể giải quyết được. Tuy nhiên, bản sao không có sẵn từ số SerializationException mà bạn gặp phải sau này, và thậm chí như vậy, giá trị sẽ chỉ có sẵn thông qua phản ánh trong ngữ cảnh tin cậy.

public class CustomSerializationBinder : SerializationBinder 
{ 
    public override Type BindToType(string assemblyName, string typeName) 
    { 
     Type t = Type.GetType(string.Concat(typeName, ", ", assemblyName)); 

     if (t == null) 
     { 
      throw new SerializationException(string.Format("Type {0} from assembly {1} could not be bound.", typeName, assemblyName)); 
     } 

     return t; 
    } 

    public override void BindToName(Type serializedType, out string assemblyName, out string typeName) 
    { 
     base.BindToName(serializedType, out assemblyName, out typeName); 
    } 
} 

... 

BinaryFormatter.Binder = new CustomSerializationBinder(); 
Các vấn đề liên quan