Common list deserialization issue with C # XmlSerializer

I ran into a brick wall with Microsoft.net XmlSerializer. I'm trying to deserialize some XML into an object, which is fine if I use one object, but the problem occurs when the object is put into a list and tries to serialize / deserialize that. First, try a sample C # console program to illustrate the problem:

http://pastebin.com/m22e6e275

If the class "Foo" is serialized as the root element, everything behaves fine, and as expected, the JezNamespace xmlns method is applied to the root Foo element and deserialization occurs fine. However, if I create a list and serialize it, the XmlSerializer: - Creates the root element ArrayOfFoo - Places the Foo elements as children of this element - Sets the xmlns of each Foo to the JezNamespace!

I'm fine with the first two, but the third seems crazy ... maybe a bug in the XmlSerializer? Is there a way to deal with this behavior? I don't want to specify my namespace for each child of Foo, I just want to specify it for Foo. If I do this, the XmlSerializer is not currently deserializing the class as expected - it just skips any Foo element using the JezNamespace xmlns set. I have to set ALL child elements to have this xmlns.

What I would like to end up with is an XmlSerializer generating something like:

<ArrayOfFoo>
    <Foo xmlns="http://schemas.datacontract.org/2004/07/JezNamespace">
        <Field1>hello</Field1>
        <Field2>world</Field2>
    </Foo>
    <Foo xmlns="http://schemas.datacontract.org/2004/07/JezNamespace">
        <Field1>aaa</Field1>
        <Field2>bbb</Field2>
    </Foo>
</ArrayOfFoo>

      

... and then the XmlSerializer will be able to deserialize this correctly into a List. Any ideas how I can get this to do this?

0


source to share


1 answer


Your code has two attributes on Foo

that as far as I can tell you put in there to try and bind the namespace:

 [XmlRootAttribute(Namespace="http://schemas.datacontract.org/2004/07/JezNamespace",
                   IsNullable=false)]
 [XmlTypeAttribute(AnonymousType=true,
                   Namespace="http://schemas.datacontract.org/2004/07/JezNamespace")]

      

The first one is simply ignored because it is Foo

not the root element in your script . The second doesn't quite do what you probably think it is - the namespace in it is the XSD type namespace, not the element's own namespace.

To specify the name and namespace of an element, you instead need to use XmlArrayItemAttribute

in the property of the List<Foo>

parent class (oh, and you need this parent class):

public class FooParent
{
    [XmlArrayItem(ElementName="Foo",
                  Namespace="http://schemas.datacontract.org/2004/07/JezNamespace")]
    public List<Foo> Foos { get; private set; }
}

      



This will give:

<FooParent>
  <Foos>
    <Foo xmlns="http://schemas.datacontract.org/2004/07/JezNamespace">
      <Field1>hello</Field1>
      <Field2>world</Field2>
    </Foo>
    ...

      

Alternatively, if you don't need an intermediate at all Foos

, you can replace XmlArrayItem

in the above text with XmlElement

. In this case, the output XML will look like this:

<FooParent>
  <Foo xmlns="http://schemas.datacontract.org/2004/07/JezNamespace">
    <Field1>hello</Field1>
    <Field2>world</Field2>
  </Foo>

      

+3


source







All Articles