2012-10-12 31 views
5

Trong hội A:deserializing có nguồn gốc loại sử dụng DataContractSerializer khi loại có nguồn gốc không được biết trước

[DataContract]  
     public class Base 
     { 
      [DataMember] 
      public string SomeText { get; set; } 
     } 

Trong hội B:

internal class Helper 
     { 
      internal static Base Deserialize(string serializedInstanceOfTypeBase) 
    { 
        DataContractSerializer serializer = new DataContractSerializer(typeof (Base)); 
        XmlReader reader = XmlReader.Create(new StringReader(serializedInstanceOfTypeBase)); 
        return (Base)serializer.ReadObject(reader); 
    } 
    } 

Trong hội C:

[DataContract]  
     public class Derived : Base 
     { 
      [DataMember] 
      public string SomeMoreText { get; set; } 
     } 

Nếu tôi serialize một thể hiện của loại Derived và vượt qua nó để Helper.Deserialize() phương pháp, nó không thành công với SerializationException:

Lỗi trong dòng 1 vị trí 2. Mong yếu tố 'cơ sở' từ namespace 'http: // schemas .datacontract.org/2004/07 '.. Đã gặp' Element ' với tên' Derived ', không gian tên ' http://schemas.datacontract.org/2004/07 '.

Tôi làm cách nào để loại bỏ vấn đề này?

Tôi biết thuộc tính KnownType, nhưng tại thời điểm mã hóa trong lắp ráp A và B, tôi hoàn toàn không nhận thức được các loại có nguồn gốc của nó. Vì vậy, tôi không thể sử dụng giải pháp đó.

Thiết kế sản phẩm của tôi phức tạp hơn nên tôi không thể đăng hoàn toàn ở đây. Phương pháp Helper.Desrialize() chỉ nhận được đối số string. Không có cách nào (ít nhất là hiện tại) để lắp ráp A hoặc B, để biết về các loại có nguồn gốc của lớp Base, ngay cả khi chạy.

hội B tham khảo lắp ráp A. Nhưng A & B không có thể tham khảo lắp ráp C.

Tôi đang sử dụng C# 4.0. Không sao nếu giải pháp bạn cung cấp KHÔNG sử dụng DataContractSerializer.

+1

Tôi không biết về giải pháp out-of-the-box. Tôi biết trong kinh nghiệm của mình khi tôi có nhiều loại, tôi thực sự sẽ sắp xếp lại hai lần nội dung của mình bằng thông tin kiểu. Tức là, tôi sẽ có một 'SerializedObject' chứa thông tin kiểu đầy đủ (tên assembly, tên lớp đầy đủ), cùng với chuỗi XML được tuần tự hóa của nó.Lớp truyền dữ liệu của tôi mạnh mẽ sẽ tự gõ vào 'SerializedObject', lấy tham chiếu thời gian chạy tới kiểu (nói qua' Type.GetType'), sau đó deserialize dữ liệu XML cho phù hợp thông qua XmlSerializer. –

+0

Bạn có nghĩa là lớp 'Base' nằm trong lớp 'Assembly A' và 'Derived' trong 'Assembly C'? Nếu điều này là như vậy thì tôi nghĩ rằng đây là vấn đề. Các hợp đồng dữ liệu nên được định nghĩa trong cùng một hội đồng. Các DataContracts không nên được chia tách trên các assembly. – jags

Trả lời

2

Bạn có biết các loại khi chạy không? Nếu vậy, một phương pháp đơn giản có thể chỉ là:

List<Type> knownTypes = ...; // now that you know what to expect 
DataContractSerializer serializer = new DataContractSerializer(
    typeof(Base), knownTypes); 
+0

Cảm ơn câu trả lời của bạn. Nó rất hữu ích nhưng tôi đã bổ sung thêm chi tiết cho câu hỏi. Tôi nên thêm những chi tiết đó trước đây. Lưu ý rằng lớp 'Helper' nằm trong các assembly khác nhau và nó không phải là' public'. Ngoài ra, phương thức 'Deserialize' chỉ nhận được bất kỳ giá trị chuỗi nào. – Learner

1

Dường như bạn cần cả hai:

  • Vượt qua một tập hợp các KnownTypes vào deserializer của bạn (như đã đề cập ở trên)
  • Cho deserializer không kiểm tra loại (sử dụng verifyObjectName tham số):

    return (Base)serializer.ReadObject(reader, false); 
    

xem chi tiết tại đây: http://msdn.microsoft.com/pl-pl/library/ms573850%28v=vs.110%29.aspx

Các vấn đề liên quan