简体   繁体   English

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

[英]How to serialize a class with a property of type object filled with an array

After searching 99% of the net I am still stuck on the following matter. 搜索了99%的网络后,我仍然坚持以下问题。 I have a web service which must comply to a wsdl that a partner company supplied. 我有一个Web服务,该服务必须符合合作伙伴公司提供的wsdl。 Calling a method of this service results in a (complex) class. 调用此服务的方法将导致一个(复杂)类。 Unfortunately a serialization error is raised when the service is called. 不幸的是,调用服务时会引发序列化错误。

I have pinpointed the issue but cannot think of (and find) a solution to it. 我已经查明了问题,但无法想到(找到)解决方案。 Because I'm dependant on the wsdl which was supplied, I cannot change the complex class structure. 因为我依赖于所提供的wsdl,所以无法更改复杂的类结构。 Hope anyone knows what I am missing. 希望任何人都知道我在想什么。 Here is example code to reproduce my issue: 这是重现我的问题的示例代码:

[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());
        }
    }
}

In the Try/Catch an error is raised after calling method Serialize(). 在“尝试/捕获”中,调用方法Serialize()后会引发错误。 Details of this error are: 此错误的详细信息是:

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

My development context consists of Visual Studio 2010, .Net Framework 3.5. 我的开发环境包括Visual Studio 2010,.Net Framework 3.5。

Edit #1: Added Serialization attributes but the error remaines 编辑#1:添加了序列化属性,但错误仍然存​​在

It appears that you cannot add an array of types to an object and serialize it. 看来您无法向object添加类型数组并对其进行序列化。 The solution was to create a container class which - like the name says - contains the array. 解决的办法是创建一个容器类,顾名思义,该类包含数组。 This way you can assign the container class to the object and serialize it all. 这样,您可以将容器类分配给object并对其进行序列化。

In addition to my case, I was mislead by the object model created by the wsdl.exe utility, since the container class is only a technical solution to add an array to an object . 除了我的案例,我还误解了wsdl.exe实用程序创建的对象模型,因为容器类只是将数组添加到object的技术解决方案。 This container class was also created so everything was already there to use. 还创建了此容器类,因此所有内容都已可以使用。 Only after trying out my custom container class I noticed the already created container class. 仅在尝试了自定义容器类之后,我才注意到已经创建的容器类。 Lost a lot of time on this matter unfortunately... 不幸的是,在这个问题上浪费了很多时间。

This is an old question, but I had the same problem and found a different solution, so I thought I'd share in case it helps someone else. 这是一个古老的问题,但是我遇到了同样的问题并找到了不同的解决方案,因此我想分享一下,以防它对其他人有所帮助。

I found that I could add attributes to allow arrays of specific types. 我发现我可以添加属性以允许特定类型的数组。 For the problem above, the MyObject class could be edited as below: 对于上述问题,可以如下编辑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
}

Anything that serialized before will still look the same, but now MyObject can be serialized even when Item has type MyItem[] , as in the question's test case. 之前进行序列化的任何内容都仍然看起来相同,但是现在MyObject可以序列化,即使Item类型为MyItem[] ,也可以在问题的测试用例中进行序列化。

You should mark you classes as 您应该将课程标记为

[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; }
}

Serialize uknown object ( Item of MyObject class) you will need to do manually by implementing proper interfaces: ISerializable and IDeserializationCallback , botha added to MyObject class. 序列化未知对象( MyObject类的Item ),您需要通过实现适当的接口来手动完成: ISerializableIDeserializationCallback ,两者都添加到MyObject类中。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM