版本控制:可以在 WCF 数据协定序列化中删除列表元素

本文关键字:序列化 删除 列表元素 数据 WCF 版本控制 | 更新日期: 2023-09-27 18:36:44

假设我有以下代码:

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(与此处接受的答案相同)问题是 DataContractSerializer 读取整个集合的内容(无论默认数组中有多少元素)。因此,如果 XML 中有 4 个元素,我的默认值列表中有 2 个元素,则我的反序列化数组中将有 4 个元素。

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

版本控制:可以在 WCF 数据协定序列化中删除列表元素

这种类型的方案应该非常适合使用数据协定代理项。

数据

协定代理项是基于数据构建的高级功能 合同模型。此功能设计用于类型 在用户想要的情况下进行自定义和替换 更改类型的序列化、反序列化或投影方式 元数据。可以使用代理项的某些情况是当数据 尚未为类型、字段和属性指定协定 未标有 DataMemberAttribute 属性或用户希望 动态创建架构变体。

序列化

和反序列化是用数据完成的 使用数据合同序列化程序从 .NET Framework 转换为合适的格式,例如 XML。数据协定 代理项还可用于修改导出的类型、 生成元数据表示形式(如 XML 架构文档)时 (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;
}