确定Object的实例是否是在WCF中可序列化的DataContract

时间:2010-12-04 19:44:27

标签: c# .net wcf serialization datacontractserializer

我正在阅读reference page关于哪些类型可以通过WCF进行序列化,并且关于哪些类型是自动KnownType并且不是这样的类型是不明确的。任何人都可以对此有所了解吗?例如,如果我的DataContract有一个Object类型的成员,如果我传递一个字符串,它将序列化很好,但如果我传递一个字典则不会。字典需要一个KnownType,尽管在该页面中被提及为支持。有了这个,我有两个问题:

  1. 所以问题是,WCF一直使用的自动KnowType是什么?

  2. 我需要能够确定默认情况下对象实例是否为KnownType的代码。一种解决方案是从答案1中提出一个详尽的列表,然后使用“obj is type”语句检查每个对象,但这似乎是一个糟糕的实现。有更聪明的方法吗?

  3. 编辑:

    reference列出了默认情况下已知的类型。所有原语都少于DateTimeOffset和XmlElement。所以只剩下两个:如何知道Object是否是原始类型?

    编辑2: typeof(obj).IsPrimitive将完成大部分工作!

1 个答案:

答案 0 :(得分:1)

当只有基类型在操作契约签名中可见时,需要一个已知类型,但可以返回一些派生类型。例如:

[OperationContract]
BaseClass Foo();

并在实施中:

public Foo()
{
    return DerivedClass();
}

其中DerivedClass来自BaseClass。因此,您需要在BaseClass声明中明确指定:

[KnownType(typeof(DerivedClass))]
[DataContract]
public class BaseClass { }

或在服务合同声明中使用[ServiceKnownType]

[ServiceContract]
[ServiceKnownType(typeof(DerivedClass))]
public interface IService
{
    [OperationContract]
    BaseClass Foo();
}

或使用配置文件:

<system.runtime.serialization>
    <dataContractSerializer>
        <declaredTypes>
            <add type="SomeNs.BaseClass, SomeAssembly">
                <knownType type="SomeNs.DerivedClass, SomeAssembly"/>
            </add>
        </declaredTypes>
    </dataContractSerializer>
</system.runtime.serialization>

更新:

正如文档所述,原始类型不需要它:

  

内置以下类型   .NET Framework都可以序列化   并被认为是原始的   类型:字节,SByte,Int16,Int32,   Int64,UInt16,UInt32,UInt64,Single,   Double,Boolean,Char,Decimal,   对象和字符串。