2012-08-09 50 views
66

我已經與.NET的XmlSerializer工作時有一個很奇怪的問題類型。使用XmlInclude或SoapInclude屬性來指定不知道靜態

看看下面的例子類:

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,有三種不同的方法來解決這個年代由串行不知道有關的派生類型Payment造成InvalidOperationException

1.添加XmlIncludePayment類定義:

這是不可能的,因爲所有的類被列爲了,我沒有控制外部引用。

2.創建XmlSerializer實例

不工作的期間過派生類型的類型。

3.定義XmlAttributeOverrides目標屬性,以覆蓋該屬性的默認序列化(如this SO post解釋)

也不起作用(XmlAttributeOverrides初始化如下)。

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); 

適當XmlSerializer構造函數將被使用。

注:不起作用我的意思是InvalidOperationExceptionBankPayment預計不會...)被拋出。

任何人都瞭解一些關於這個問題光?如何進一步解決問題?

回答

29

就解決了這個問題。經過一段時間的挖掘後,我發現this SO post涵蓋了完全相同的情況。它讓我走上了正軌。

基本上,XmlSerializer需要知道默認命名空間如果派生類作爲額外的類型包含在內。這種事情發生的確切原因還不得而知,但現在序列化仍在進行。

63

這爲我工作:

[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

所以基本類型需要知道所有的實現?這似乎不是一個很好的解決方案。沒有其他辦法嗎? – 2014-07-03 08:10:01

+1

@AlexanderStolz在創建XmlSerializable對象時通過新類型的泛型實現是最佳解決方案。正如提到http://stackoverflow.com/a/2689660/698127 – Aamol 2015-07-29 01:23:50