【问题标题】:Versioning: Possible to remove list elements in WCF DataContract serialization?版本控制:可以删除 WCF DataContract 序列化中的列表元素吗?
【发布时间】:2015-01-08 19:43:13
【问题描述】:

假设我有以下代码:

namespace Test
{
    [DataContract()]
    internal class Class2 : AbstractSerializeableObject
    {
        [DataMember()]
        int[] ints;

        protected override XMLVersion ObjectVersion
        {
            get { return version; }
        }
        [DataMember()]
        private XMLVersion version = new XMLVersion(1, 0, 0, "Test");

        protected override void SetDefaults()
        {
            ints = new int[] { 1, 2, 3, 4 };
        }
    }
}

最终序列化为以下 XML 文件:

<?xml version="1.0" encoding="utf-8"?>
<Class2 xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.datacontract.org/2004/07/Test">
    <ints xmlns:d2p1="http://schemas.microsoft.com/2003/10/Serialization/Arrays">
        <d2p1:int>1</d2p1:int>
        <d2p1:int>2</d2p1:int>
        <d2p1:int>3</d2p1:int>
        <d2p1:int>4</d2p1:int>
    </ints>
    <version xmlns:d2p1="http://schemas.datacontract.org/2004/07/XMLSerializationLib">
        <d2p1:description></d2p1:description>
        <d2p1:major>1</d2p1:major>
        <d2p1:minor>0</d2p1:minor>
        <d2p1:patch>0</d2p1:patch>
        <d2p1:title>Test</d2p1:title>
    </version>
</Class2>

现在我想从我的ints 数组中删除几个元素。我的AbstractSerializeableObject 设计为在序列化或调用构造函数时调用SetDefaults(以与接受的答案here 相同的方式)问题是DataContractSerializer 读取整个集合的内容(无论默认数组中有多少元素)。因此,如果 XML 中有 4 个元素,我的默认值列表中有 2 个元素,那么我的反序列化数组中将有 4 个元素。

有什么方法可以修复集合的大小,以便在反序列化时省略 XML 文件中的额外值?

【问题讨论】:

  • 您无法更改数组的大小。为什么不使用 List
  • 这不是问题;如果我使用列表、数组甚至字典,我也会遇到同样的问题;真的是任何收藏。
  • 假设我在 DataContract 的第一个版本中使用 5 个元素初始化数组。然后假设我对合同进行了修改,而是只用 3 个元素对其进行了初始化。当前一个合约的 XML 文件用新合约反序列化时,它会拉入 5 个元素而不是 3 个。

标签: c# xml wcf serialization collections


【解决方案1】:

这种场景应该很适合Data Contract Surrogates的使用。

数据合约代理是建立在数据之上的高级功能 合同模型。此功能旨在用于类型 在用户想要的情况下进行定制和替换 更改类型序列化、反序列化或投影到的方式 元数据。可以使用代理的一些场景是当数据 没有为类型、字段和属性指定合同 未使用 DataMemberAttribute 属性标记或用户希望 动态创建架构变体。

序列化和反序列化是通过数据完成的 使用 DataContractSerializer 转换时的合约代理 .NET Framework 转换为合适的格式,例如 XML。数据合约 surrogate 也可用于修改为类型导出的元数据, 生成元数据表示(例如 XML Schema Documents)时 (XSD)。导入后,从元数据和代理项创建代码 在这种情况下也可以用来自定义生成的代码。

例如,在您的情况下 使序列化的 XML 中只包含 2 个元素:

public object GetObjectToSerialize(object obj, Type targetType)
{
    Console.WriteLine("GetObjectToSerialize");
    if (obj is Class2)
    {
        Class2Surrogated c2sur = new Class2Surrogated();
        c2sur.ints = ((Class2Surrogated)obj).ints.Take(2).ToArray();
        c2sur.version = ((Class2Surrogated)obj).version;
        return c2sur;
    }
    return obj;
}

【讨论】:

    猜你喜欢
    • 2011-06-07
    • 2018-09-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多