C# 确定对象的实例在WCF中是否可以序列化DataContract

C# 确定对象的实例在WCF中是否可以序列化DataContract,c#,.net,wcf,serialization,datacontractserializer,C#,.net,Wcf,Serialization,Datacontractserializer,我读的是关于什么类型可以被WCF序列化的文章,关于什么类型可以自动地被KnownType序列化,什么类型不能被自动地KnownType序列化,这是不明确的。有人能解释一下吗?例如,如果我的DataContract有一个Object类型的成员,那么如果我传递一个字符串,它将很好地序列化,但如果我传递一个字典,它将不会序列化。这本词典需要一个KnownType,尽管该页面中提到了支持它。关于这一点,我有两个问题: 所以问题是,WCF总是使用哪些自动知识类型 我需要一段代码来判断对象的实例是否默认为K

我读的是关于什么类型可以被WCF序列化的文章,关于什么类型可以自动地被KnownType序列化,什么类型不能被自动地KnownType序列化,这是不明确的。有人能解释一下吗?例如,如果我的DataContract有一个Object类型的成员,那么如果我传递一个字符串,它将很好地序列化,但如果我传递一个字典,它将不会序列化。这本词典需要一个KnownType,尽管该页面中提到了支持它。关于这一点,我有两个问题:

  • 所以问题是,WCF总是使用哪些自动知识类型

  • 我需要一段代码来判断对象的实例是否默认为KnownType。一个解决方案是从1的答案中列出一个详尽的列表,然后用“obj is type”语句对照每个对象检查对象,但这似乎是一个糟糕的实现。有更聪明的方法吗

  • 编辑:

    这将列出默认情况下已知的类型。所有原语减去DateTimeOffset加上XmlElement。所以只剩下两个问题:我如何知道一个对象是否是基元类型

    编辑2:
    typeof(obj)。iPrimitive将完成大部分工作

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

    [OperationContract]
    BaseClass Foo();
    
    在实施过程中:

    public Foo()
    {
        return DerivedClass();
    }
    
    其中,
    DerivedClass
    派生自
    BaseClass
    。因此,您需要在
    BaseClass
    声明中明确指定这一点:

    [KnownType(typeof(DerivedClass))]
    [DataContract]
    public class BaseClass { }
    
    [ServiceContract]
    [ServiceKnownType(typeof(DerivedClass))]
    public interface IService
    {
        [OperationContract]
        BaseClass Foo();
    }
    
    或在服务合同声明中使用:

    [KnownType(typeof(DerivedClass))]
    [DataContract]
    public class BaseClass { }
    
    [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都可以序列化 被认为是原始的 类型:Byte、SByte、Int16、Int32、, Int64、UInt16、UInt32、UInt64、单, 双精度、布尔值、字符、十进制、, 对象和字符串


    你至少部分错了。KnownType还有其他用途。例如,如果我没有为字典添加KnownType,就会出现序列化异常。你也没有回答我的两个问题:-(我投了否决票,但如果你编辑答案以真正解决我的问题,我会收回它。同样,我不会问KnownType做什么。这对
    字典
    来说很奇怪。我没有任何例外。你确定你说的不是另一个故事
    IDictionary
    。你能解释一下否决票吗?
    Dictionary
    是一个可由
    DataContractSerializer
    完全序列化的类型。只需使用默认模板创建一个新的WCF应用程序,将自动生成的方法
    GetData
    的返回类型从string更改为
    Dictionary
    ,运行并调用该服务。它工作正常。请记住,我是serializ正在序列化一个对象,在运行时它恰好是一个字典,因此需要KnownType。所以问题仍然是,在这种情况下,是不需要KnownType的类型,以及如何检查对象是否属于其中一种类型?您正在序列化什么对象?您的操作契约看起来如何?正如我在回答中解释的,每个派生类型都可能是这样的您的方法可能返回的类型需要知道,因此如果您的方法签名看起来像
    object GetFoo()
    ,那么您应该列出所有可能的类型,以便WSDL可以公开这些类型。方法签名中未出现的每种类型都需要知道。