【问题标题】:type xxxx not expected use xmlinclude or soapinclude类型 xxxx 不应使用 xmlinclude 或 soapinclude
【发布时间】:2013-11-28 23:51:31
【问题描述】:

我有一个关于这个序列化问题的奇怪案例 - 在这个网站上已经被问过很多次,我已经解决了其中一些问题并尝试了通常的项目无济于事:

  • 将 [XmlInclude] 添加到引发错误的类中
  • 删除命名空间
  • 为每个类添加不同的命名空间

为了进一步解释,我在下面提供了我的代码的简化版本。本质上,我使用WebServiceHost 对象来运行RESTful 服务,并且我的一个端点返回一个序列化为XML 的对象(我已使用[DataContract][DataMember] 属性注释了该对象)。此对象包含一个SerializableDictionary<string, object> (here),其中值已输入为object。我相信这就是它失败的原因:

  • 当值被分配一个原语时工作正常
  • 当我将自定义对象分配给 KV 对 V 时,我得到 unexpected type 异常,可能是因为序列化程序不知道如何序列化对象/某种命名空间问题

显然,我无法使用 [XmlInclude] 注释 Object.cs,而且因为它是一项服务,而且我自己没有序列化,所以我不能使用类似的东西

new Serializer(typeof(...), new Type[] { ... }}

知道我能做什么吗?我考虑过不要将 dict 值键入为对象,而是更具体,但问题是该值可以采用原语或自定义类型。一些解释上述内容的代码:

编辑:更新了下面的代码,使其更清晰

[DataContract]
public class ResponseObject
{
    [DataMember(Name = "data")]
    public SerializableDictionary<string, object> Data { get;set; }

    public ResponseObject()
    {
        Data = new SerializableDictionary<string, object>();
    }
}

...

var d1 = new ResponseObject();
d1.Data.Add("some key", "some value"); //WORKS AND SERIALIZES PERFECLTY

var d2 = new ResponseObject();
d2.Data.Add("some other key", new SomeOtherObjecT());
var d3 = new ResponseObject();
d3.Data.Add("another key", d2);  //THIS THROWS THE UNEXPECTED TYPE ERROR WHEN SEIRLAIZING SomeOtherObject

编辑: 在尝试序列化 ResponseObject 类型的对象的 SerializableDictionary 中引发错误。两者处于不同的项目中 - 如果这很重要吗?

【问题讨论】:

    标签: c# xml rest serialization


    【解决方案1】:

    通常,您应该将 [XmlInclude] 添加到 ResponseObject 类。在这种情况下,由于您使用的是 SerializableDictionary,它不起作用。该类在其实现中创建了另一个 XmlSerializer,因此它不关心您的 [XmlInclude]。基本上它只是无法处理您的用例。您应该从 XmlSerializer 切换到处理 Dictionary 类并支持 [KnownType] 属性来注册其他类型的 DataContractSerializer:http://pastebin.com/vGLSaxHF。另请注意,在当前情况下添加 [DataContract] 和 [DataMember] 属性是没有意义的,因为 XmlSerializer 会忽略这些属性,它们仅由 DataContractSerializer 使用。或者,如果您不确定如何更改序列化程序(我知道我不是),那么您不应该使用 Dictionary 或更改 SerializableDictionary 实现来处理您想要使用的动态对象类型(找到每一行它创建一个新的 XmlSerializer)。或者,作为替代方案,为您将放入字典中的所有对象定义一个基类并像这样:

    [XmlInclude(typeof(Class1), XmlInclude(typeof(Class2)), etc]
    public class AbstractBase { }
    
    public class Class1 : AbstractBase { ... }
    
    public class Class2 : AbstractBase { ... }
    
    public class BigClass {
        public SerializableDictionary<string, AbstractBase> Dictionary { get; set; }
    }
    

    这样,当 SerializableDictionary 创建自己的 XmlSerializer 时,它将识别 AbstractBase 并从那里识别它的所有后代。

    【讨论】:

      猜你喜欢
      • 2012-08-06
      • 1970-01-01
      • 1970-01-01
      • 2020-07-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-03-31
      • 1970-01-01
      相关资源
      最近更新 更多