如何使用DataContracts正确序列化从集合派生的类

时间:2013-04-10 20:38:33

标签: c# .net serialization datacontractserializer xmlserializer

在C#和.NET 4.5中,我正在通过DataContract序列化实现XML生成/解析,这看起来非常有效。 但是,在一些情况下我遇到了一些问题,我希望有人可以帮助我。

相关的类是以下5个(加上一些嵌入的对象):

[DataContract]
public abstract class ItemList<T> : List<T>, IList
  {
  .....
  }

[DataContract]
public class CashFlowList : ItemList<CashFlow>
  {
  .....
  }

[DataContract]
public class CashFlow : ItemList<CashFlowPayment>  
  {
  .....
  }

[DataContract]
public class CashFlowPayment : ListItem, IDataImportExport
  {
  .....
  }

[DataContract]
public abstract class ListItem : System.IComparable, IList
  {
  .....
  }

使用DataContractSerializer(在CashFlowList类型上)时,生成的XML如下所示:

<CashFlowList xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.datacontract.org/2004/07/FinancialData">
  <_items>
    <CashFlow>
      <_items>
        <CashFlowPayment>
          <ID>-1</ID>
          <ProbDist xmlns:d6p1="http://schemas.datacontract.org/2004/07/ProbabilityDistributions" i:nil="true" />
          <UseProbabilityDistribution>true</UseProbabilityDistribution>
          <ValidFrom>0001-01-01T00:00:00</ValidFrom>
          <ValidThrough>9999-12-31T23:59:59.9999999</ValidThrough>
          <Amount>4500</Amount>
          <Ccy i:nil="true" />
          <Date>2012-02-03T00:00:00</Date>
          <DaysFromStartDate>-1</DaysFromStartDate>
        </CashFlowPayment>
        <CashFlowPayment>
          <ID>-1</ID>
          <ProbDist xmlns:d6p1="http://schemas.datacontract.org/2004/07/ProbabilityDistributions" i:nil="true" />
          <UseProbabilityDistribution>true</UseProbabilityDistribution>
          <ValidFrom>0001-01-01T00:00:00</ValidFrom>
          <ValidThrough>9999-12-31T23:59:59.9999999</ValidThrough>
          <Amount>-30000</Amount>
          <Ccy i:nil="true" />
          <Date>2013-04-10T00:00:00+02:00</Date>
          <DaysFromStartDate>465</DaysFromStartDate>
          <DaysUntilEndDate>-1</DaysUntilEndDate>
          <IsPerpetual>false</IsPerpetual>
          <PaymentType>Unknown</PaymentType>
          <Schedule xmlns:d6p1="http://schemas.datacontract.org/2004/07/Schedules" i:nil="true" />
        </CashFlowPayment>
        <CashFlowPayment i:nil="true" />
        <CashFlowPayment i:nil="true" />
      </_items>
      <_size>2</_size>
      <_version>3</_version>
      <ID>-1</ID>
      <Name></Name>
      <ProbDist xmlns:d4p1="http://schemas.datacontract.org/2004/07/ProbabilityDistributions" i:nil="true" />
      <UseProbability>false</UseProbability>
      <ValidFrom>0001-01-01T00:00:00</ValidFrom>
      <ValidThrough>9999-12-31T23:59:59.9999999</ValidThrough>
      <BaseCCY></BaseCCY>

 ..............................

       <StartDate>2012-05-09T00:00:00</StartDate>
      <SumOfNegativePayments>-30000</SumOfNegativePayments>
      <SumOfPositivePayments>4500</SumOfPositivePayments>
      <ValueDate>0001-01-01T00:00:00</ValueDate>
      <XMLCashFlowElementName i:nil="true" />
      <XMLPaymentElementName i:nil="true" />
      <XMLPaymentsElementName i:nil="true" />
    </CashFlow>
    <CashFlow i:nil="true" />
    <CashFlow i:nil="true" />
    <CashFlow i:nil="true" />
  </_items>
  <_size>1</_size>
  <_version>1</_version>
  <ID>-1</ID>
  <Name></Name>
  <ProbDist xmlns:d2p1="http://schemas.datacontract.org/2004/07/ProbabilityDistributions" i:nil="true" />
  <UseProbability>false</UseProbability>
  <ValidFrom>0001-01-01T00:00:00</ValidFrom>
  <ValidThrough>9999-12-31T23:59:59.9999999</ValidThrough>
</CashFlowList>

生成的XML是正确的 - 但有许多怪癖:首先是&lt; _items&gt;我认为串行器管理输出所需的元素。  其次,你会注意到每个集合 - 在&lt; _items&gt;内。元素总是至少有4个子元素 - 例如,添加另一个CashFlow  外部将只产生2个元素 - 为什么,有没有办法解决这个问题?

用[CollectionDataContract]替换一个或多个[DataContract]属性 - 无论属性中设置了什么属性 - 都将生成  按预期语法正确的XML输出,但现在 - 对于具有[CollectionDataContract]属性的每个类 - 仅输出集合 - 而不是常规  类中的属性。即一个例子是:

<CashFlowList xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.datacontract.org/2004/07/FinancialData">
  <CashFlow>
    <CashFlowPayment>
    ....
    </CashFlowPayment>      
  </CashFlow>    
</CashFlowList>  

在上面的示例中,忽略了以下元素(在外部CashFlowList对象中):

  <ID>-1</ID>
  <Name></Name>
  <ProbDist xmlns:d2p1="http://schemas.datacontract.org/2004/07/ProbabilityDistributions" i:nil="true" />
  <UseProbability>false</UseProbability>
  <ValidFrom>0001-01-01T00:00:00</ValidFrom>
  <ValidThrough>9999-12-31T23:59:59.9999999</ValidThrough>

所以我的问题是这是否是设计并且是不可避免的 - 即你可以输出一个派生自集合的类并在输出中包含其他属性 何时使用[CollectionDataContract]属性?

有趣的是,如果使用[CollectionDataContract]属性,则可以使用XsdDataContractExporter类生成/检索相应的XSD,而无需 问题(由于缺少属性,XML不完整)。但是,使用[DataContract]属性时,无法生成XSD(失败) CanExport方法),但XML是正确和完整的,但不是特别清晰。

因此,我非常感谢您对此有任何见解和/或想法。

致以最诚挚的问候和谢谢,

迈克尔

0 个答案:

没有答案