none
请教关于数据契约序列化的问题 RRS feed

  • 问题

  • 背景:有两个类Class1和Class2,Class2继承Class1。
    当我使用配置文件配置已知类型时,如下:
    <system.runtime.serialization>
        <dataContractSerializer>
          <declaredTypes>
            <add type="System.Object, mscorlib, Version=2.0.0.0, Culture=neutral, Publickeytoken=b77a5c561934e089">
              <knownType type="DataContact.Class2, DataContact" />
            </add>
          </declaredTypes>
        </dataContractSerializer>   
      </system.runtime.serialization>
    系统抱错,而将System.Object改为:DataContact.Class1类型时则通过。

    请问是我配置的有问题,还是wcf不支持Object为父类的类型。
    2010年1月5日 16:13

答案

  • 可能wcf不支持直接标注KnownType到Object上。一种办法是创建一个类(Class3)来包裹Object对象,然后标注KnownType到Class3上。

            [DataContract]
            public class Class3
            {
                [DataMember]
                Object WrappedObject;
            }

            <add type="DataContact.Class3,DataContact">
              <knownType type="DataContact.Class2, DataContact" />
            </add>

    这样,就可以传递Object对象并且成功解析Class2 类型


    Mog Liang
    • 已标记为答案 Jiyuan 2010年1月7日 13:38
    2010年1月7日 7:08

全部回复

  • Hi,

    1.我没做过测试,你尝试一下修改一下配置。
    我猜测需要增加 SerializationTypes。
     <add type="System.Collections.Generic.Dictionary`2, SerializationTypes, Version = 2.0.0.0, Culture = neutral, PublicKeyToken=null">
              <knownType type="System.Collections.Generic.List`1, SerializationTypes, Version = 2.0.0.0, Culture = neutral, PublicKeyToken=null">
                <parameter index="1"/>
              </knownType>
            </add>
    WCF需要类型支持序列化。
    参考这里的例子:
    http://msdn.microsoft.com/zh-cn/library/ms731806.aspx
    Frank Xu Lei--谦卑若愚,好学若饥
    专注于.NET平台下分布式应用系统开发和企业应用系统集成
    Focus on Distributed Applications Development and EAI based on .NET
    欢迎访问老徐的中文技术博客:Welcome to My Chinese Technical Blog
    欢迎访问微软WCF中文技术论坛:Welcome to Microsoft Chinese WCF Forum
    欢迎访问微软WCF英文技术论坛:Welcome to Microsoft English WCF Forum
    2010年1月6日 10:08
    版主
  • hi Frank,
    改后仍然无效,按常识你提供的SerializationTypes所在的配置文件中的位置应该是程序集的名称,不知道这里的SerializationTypes有什么特别的?
    另如果将配置信息改为:
    <add type="System.Object, SerializationTypes, Version=2.0.0.0, Culture=neutral, Publickeytoken=b77a5c561934e089">
    则系统抱错并提示:
    属性“type”的值无效。错误为: 给定程序集名称或基本代码无效。 (异常来自 HRESULT:0x80131047)

    如果将配置信息改为:
    <add type="System.Object, mscorlib, Version=2.0.0.0, Culture=neutral, Publickeytoken=b77a5c561934e089">
    属性“type”的值无效。错误为: 类型 System.Object 不能用作配置中声明的类型。

    而将配置信息改为:
    <add type="DataContact.Class1, DataContact">
    则代码执行通过。
    2010年1月6日 13:38
  • 可能wcf不支持直接标注KnownType到Object上。一种办法是创建一个类(Class3)来包裹Object对象,然后标注KnownType到Class3上。

            [DataContract]
            public class Class3
            {
                [DataMember]
                Object WrappedObject;
            }

            <add type="DataContact.Class3,DataContact">
              <knownType type="DataContact.Class2, DataContact" />
            </add>

    这样,就可以传递Object对象并且成功解析Class2 类型


    Mog Liang
    • 已标记为答案 Jiyuan 2010年1月7日 13:38
    2010年1月7日 7:08
  • 可能wcf不支持直接标注KnownType到Object上。一种办法是创建一个类(Class3)来包裹Object对象,然后标注KnownType到Class3上。

            [DataContract]
            public class Class3
            {
                [DataMember]
                Object WrappedObject;
            }

            <add type="DataContact.Class3,DataContact">
              <knownType type="DataContact.Class2, DataContact" />
            </add>

    这样,就可以传递Object对象并且成功解析Class2 类型


    Mog Liang

    太感谢您了,您的方法很有效。的确是奇妙的想法。只是美中不足的是,需要修改服务契约。
    我也找了很久,好像wcf确实不支持直接对Object标示KnownType。
    多少有点违背OO的思想,不知道这是不是OO与SOA的利弊权衡的结果!
    2010年1月7日 13:36