【问题标题】:Is it possible to define your own conversion for a type during serialization?是否可以在序列化期间为类型定义自己的转换?
【发布时间】:2017-01-13 07:59:39
【问题描述】:

我在一个类型上使用[DataContract] 属性使其可序列化。一些属性/字段是结构类型,我不想按原样序列化,但想严格使用自定义类型进行序列化。

如何用类型替换序列化?

【问题讨论】:

  • 太棒了,这正是我需要的,让它成为答案,我会标记它
  • 我不想提供仅链接的答案,但很乐意提供帮助。
  • 好吧,如果您想花时间给出一个简短的概述,那也可以:) 在网上搜索了很多东西,但在这里我找不到我需要的东西,尽管我认为有一个方法来做到这一点。当然,我没有意识到关键字是代理。

标签: c# .net serialization datacontract


【解决方案1】:

当您在 .NET 中使用 [DataContract] 属性时,通常最终会使用 DataContractSerializer 序列化类型。 DataContractSerializer 有一个名为 DataContractSurrogate 的只读属性。该属性是一个IDataContractSurrogate 接口。 (只读属性可以在构造函数上设置,也可以通过DataContractSerializerSettings类型设置)

该接口包含在序列化期间将一种类型转换为另一种类型的逻辑。接口提供了 8 种方法,但是在序列化和反序列化期间将一种类型转换为另一种类型,您实际上只需要实现 3 个。这是实现接口的类的基本结构,您可以在其中替换类型和转换逻辑.

internal class SerializerSurrogate : IDataContractSurrogate
{
    /// <summary>
    /// Identifies a type transformation.
    /// </summary>
    /// <param name="type">The type being inspected.</param>
    /// <returns>The type to transform to. If the same type is used, transform does not happen.</returns>
    public Type GetDataContractType(Type type)
    {
        if (type == typeof(sourceType))
            return typeof(targetType);

        return type;
    }

    /// <summary>
    /// During serialization, transfrom from sourceType to targetType.
    /// </summary>
    /// <param name="obj">The object instance.</param>
    /// <param name="targetType">The source type.</param>
    /// <returns>A new object instance based on targetType.</returns>
    public object GetObjectToSerialize(object obj, Type targetType)
    {
        if (obj is sourceType)
        {
            // Create instance of targetType from the obj variable which is sourceType
            // Set the properties of the targetType, based on the (sourceType)obj variable.
            return new targetType();
        }

        return obj;
    }

    /// <summary>
    /// During deserialization, transform from targetType to sourceType.
    /// </summary>
    /// <param name="obj">The object instance.</param>
    /// <param name="targetType">The target type.</param>
    /// <returns>A new object instance based on sourceType.</returns>
    public object GetDeserializedObject(object obj, Type targetType)
    {
        if (obj is targetType)
        {
            // Create instance of sourceType from the obj variable which is targetType
            // Set the properties of the sourceType, based on the (targetType)obj variable.
            return new sourceType();
        }

        return obj;
    }

    public object GetCustomDataToExport(Type clrType, Type dataContractType)
    {
        throw new NotImplementedException();
    }

    public object GetCustomDataToExport(MemberInfo memberInfo, Type dataContractType)
    {
        throw new NotImplementedException();
    }

    public void GetKnownCustomDataTypes(Collection<Type> customDataTypes)
    {
        throw new NotImplementedException();
    }

    public Type GetReferencedTypeOnImport(string typeName, string typeNamespace, object customData)
    {
        return null;
    }

    public CodeTypeDeclaration ProcessImportedType(CodeTypeDeclaration typeDeclaration, CodeCompileUnit compileUnit)
    {
        return null;
    }
}

【讨论】:

    猜你喜欢
    • 2011-12-29
    • 1970-01-01
    • 2014-07-05
    • 1970-01-01
    • 2013-05-30
    • 1970-01-01
    • 2019-08-23
    • 2017-10-08
    • 1970-01-01
    相关资源
    最近更新 更多