XML Serialization of an object initialized as array

前端 未结 1 536
清歌不尽
清歌不尽 2021-01-25 01:51

My question is probably arising from a basic misunderstanding of XML serialization, but anyways...
I\'m trying to serialize a class containing an object which was initialize

相关标签:
1条回答
  • 2021-01-25 02:28

    Your difficulty arises from the fact that XmlSerializer requires all types to be serialized to be discoverable statically, through reflection. However, your type MyClass has a polymorphic object property where a instance of a subtype of object -- specifically string [] -- is being stored. When XmlSerializer encounters it, since objects of this type are not expected, the serializer throws the exception you see.

    When serializing polymorphic properties such as this, it is necessary to use XML serialization attributes to declare the types that can be encountered. XmlSerializer provides two mechanisms to accomplish this.

    1. Declare the possible polymorphic subtypes using XmlInclude(Type) attributes on the containing type. Since string and string [] are the possible types of your object property, you would do:

      [XmlInclude(typeof(string))]
      [XmlInclude(typeof(string[]))]
      public class MyClass
      {
          public object myObject { get; set; }
      
          public MyClass()
          {
              myObject = new string[] { "somestring" };
          }
      }
      

      And the resulting XML will look like:

      <MyClass xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
          <myObject xsi:type="ArrayOfString">
              <string>somestring</string>
          </myObject>
      </MyClass>
      

      Notice the xsi:type attribute? That is a w3c standard attribute that allows the element to assert its type explicitly. Its presence allows XmlSerializer to deserialize the XML into the same type of objects as were originally serialized.

      (Note that [XmlInclude(typeof(string))] seems to be unnecessary as string is apparently a built-in known type - though I cannot find documentation confirming this.)

    2. Declare the possible polymorphic subtypes using [XmlElement(String, Type)] on the polymorphic property itself. Thus you would do something like:

      public class MyClass
      {
          [XmlElement("myObjectString", typeof(string))]
          [XmlElement("myObjectStringArray", typeof(string[]))]
          public object myObject { get; set; }
      
          public MyClass()
          {
              myObject = new string[] { "somestring" };
          }
      }
      

      And the XML generated will look like:

      <MyClass xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
          <myObjectStringArray>
              <string>somestring</string>
          </myObjectStringArray>
      </MyClass>
      

      Notice that the name of the myObject element been modified to the string passed to into the [XmlElement(String, Type)] attribute constructor. This allows XmlSerializer to deserialize the XML into the same type of objects as were originally serialized.

    0 讨论(0)
提交回复
热议问题