2012-08-09 39 views
66

Tôi gặp vấn đề rất lạ khi làm việc với .NET XmlSerializer.Sử dụng thuộc tính XmlInclude hoặc SoapInclude để chỉ định các loại không được biết tĩnh

Lấy lớp ví dụ sau:

public class Order 
{ 
    public PaymentCollection Payments { get; set; } 

    //everything else is serializable (including other collections of non-abstract types) 
} 

public class PaymentCollection : Collection<Payment> 
{ 
} 

public abstract class Payment 
{ 
    //abstract methods 
} 

public class BankPayment : Payment 
{ 
    //method implementations 
} 

AFAIK, có ba phương pháp khác nhau để giải quyết vấn InvalidOperationException đó là do serializer không biết về các loại có nguồn gốc của Payment.

1. Thêm XmlInclude định nghĩa Payment lớp:

Đây là không thể do tất cả các lớp học được bao gồm như là tài liệu tham khảo bên ngoài mà tôi không có quyền kiểm soát.

2. Đi qua các loại các loại có nguồn gốc trong quá trình tạo của XmlSerializer dụ

Không làm việc.

3. Xác định XmlAttributeOverrides cho các tài sản mục tiêu để ghi đè serialization mặc định của tài sản (như đã giải thích ở this SO post)

Cũng không hoạt động (XmlAttributeOverrides khởi sau).

Type bankPayment = typeof(BankPayment); 

XmlAttributes attributes = new XmlAttributes(); 
attributes.XmlElements.Add(new XmlElementAttribute(bankPayment.Name, bankPayment)); 

XmlAttributeOverrides overrides = new XmlAttributeOverrides(); 
overrides.Add(typeof(Order), "Payments", attributes); 

Sau đó, hàm tạo thích hợp XmlSerializer sẽ được sử dụng.

LƯU Ý: bởi không hoạt động Tôi có nghĩa là InvalidOperationException (BankPayment không được trông đợi ...) được ném.

Có ai có thể làm sáng tỏ chủ đề này không? Làm thế nào sẽ đi về và gỡ lỗi vấn đề hơn nữa?

Trả lời

29

Chỉ cần giải quyết vấn đề. Sau khi đào bới trong một thời gian lâu hơn, tôi tìm thấy this SO post trong đó bao gồm chính xác cùng một tình huống. Nó giúp tôi đi đúng hướng.

Về cơ bản, XmlSerializer cần biết không gian tên mặc định nếu các lớp dẫn xuất được bao gồm làm loại bổ sung. Lý do chính xác tại sao điều này đã xảy ra vẫn chưa được biết nhưng, vẫn còn, serialization đang làm việc ngay bây giờ.

63

này đã làm việc cho tôi:

[XmlInclude(typeof(BankPayment))] 
[Serializable] 
public Payment { }  

[Serializable] 
public class BankPayment : Payment {} 

[Serializable] 
public class Payments : List<Payment>{} 

XmlSerializer serializer = new XmlSerializer(typeof(Payments), new Type[]{typeof(Payment)}); 
+5

Vì vậy, các loại hình cơ bản cần phải biết tất cả các hiện thực của nó? Điều này dường như không phải là một giải pháp rất tốt. Có không có cách nào khác? –

+1

@AlexanderStolz để triển khai chung loại mới khi tạo đối tượng XmlSerializable là giải pháp tốt nhất. Như đã đề cập http://stackoverflow.com/a/2689660/698127 – Aamol

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