如何使用填充了数组的object类型的属性序列化类

时间:2012-02-28 14:24:00

标签: c# visual-studio-2010 serialization .net-3.5

在搜索了99%的网后,我仍然坚持以下事项。我有一个Web服务,必须遵守合作伙伴公司提供的wsdl。调用此服务的方法会产生(复杂)类。不幸的是,在调用服务时会引发序列化错误。

我已经确定了问题,但却无法想到(并找到)解决方案。因为我依赖于提供的wsdl,所以我无法改变复杂的类结构。希望有人知道我错过了什么。以下是重现我的问题的示例代码:

[System.SerializableAttribute()]
public class MyObject
{
    public int Id { get; set; }
    public object Item { get; set; }    // <---- Note type *object* here
}

[System.SerializableAttribute()]
public class MyItem
{
    public int Id { get; set; }
    public string Name { get; set; }
}

[TestClass]
public class SerializationTest
{
    [TestMethod]
    public void Serializing()
    {
        MyObject myObject = new MyObject { Id = 1 };
        myObject.Item = new MyItem[] { new MyItem { Id = 1, Name = "Test" } };

        string serializedString = SerializeObjectToXmlString(myObject, new []{ typeof(MyItem)});

        Assert.IsFalse(String.IsNullOrWhiteSpace(serializedString));
    }

    /// <summary> 
    /// This method serializes objects to an XML string using the XmlSerializer 
    /// </summary> 
    private static string SerializeObjectToXmlString(object theObject, Type[] types)
    {
        using (var oStream = new System.IO.MemoryStream())
        {
            var oSerializer = new System.Xml.Serialization.XmlSerializer(theObject.GetType(), types);

            oSerializer.Serialize(oStream, theObject);  // <- Here the error is raised

            return System.Text.Encoding.Default.GetString(oStream.ToArray());
        }
    }
}

在Try / Catch中,调用方法Serialize()后会引发错误。此错误的详细信息如下:

InvalidOperationException was unhandled by user code
- There was an error generating the XML document.
  The type MyItem[] may not be used in this context.

我的开发环境包括Visual Studio 2010,.Net Framework 3.5。

编辑#1:添加了序列化属性,但错误仍然存​​在

3 个答案:

答案 0 :(得分:1)

您似乎无法向object添加类型数组并对其进行序列化。解决方案是创建一个容器类 - 就像名字所说 - 包含数组。这样,您可以将容器类分配给object并将其全部序列化。

除了我的情况,我被wsdl.exe实用程序创建的对象模型误导,因为容器类只是将数组添加到object的技术解决方案。此容器类也已创建,因此所有内容都已在那里使用。只有在尝试我的自定义容器类后,我才注意到已经创建的容器类。遗憾的是,在这件事上失去了很多时间......

答案 1 :(得分:0)

您应该将课程标记为

[Serializable]
public class MyObject
{
  public int Id { get; set; }
  public MyItem[] Item { get; set; }    // <---- Note type *object* here
}

[Serializable]
public class MyItem
{
  public int Id { get; set; }
  public string Name { get; set; }
}

序列化未知对象( MyObject 类的 Item ),您需要通过实现适当的接口手动完成: ISerializableIDeserializationCallback,botha已添加到 MyObject 类。

答案 2 :(得分:0)

这是一个古老的问题,但是我遇到了同样的问题,并且找到了不同的解决方案,所以我想分享一下,以防它对其他人有所帮助。

我发现我可以添加属性以允许特定类型的数组。对于上述问题,MyObject类可以如下进行编辑:

[System.SerializableAttribute()]
public class MyObject
{
    public int Id { get; set; }
    [XmlElement(Type = typeof(object), ElementName = "Item"), //added
        XmlElement(Type = typeof(MyItem[]), ElementName = "Item_asArrayOfMyItem")] //added
    public object Item { get; set; }    // <---- Note type *object* here
}

之前进行序列化的所有内容看起来都相同,但是现在MyObject可以序列化,即使Item的类型为MyItem[],如问题的测试用例一样。