Problem deserializing generic List's with C# XmlSerializer
I've come up against a bit of a brick wall with Microsoft's .net XmlSerializer. I'm trying to deserialize some XML into an object, which is fine if I'm using a single object, but the problem comes when one puts an object into a List and tries to serialize/deserialize that. First up, here's a sample C# windows console program to illustrate the problem:
http://pastebin.com/m22e6e275
If the class 'Foo' is serialized as a root element, things behave fine, and as expected - the JezNamespace xmlns is applied to the root Foo element, and deserialization occurs fine. However if I create a List and serialize that, the XmlSerializer: - Creates a root element of ArrayOfFoo - Puts the Foo elements as children of that element - Sets the xmlns of EVERY child of Foo to the JezNamespace namespace!
I'm OK with the first two, but the third one seems mad... maybe a bug in XmlSerializer? Is there some way I can deal with this behaviour? I don't want to be specifying my namespace for every child of Foo, I just want to specify it for Foo. If I do that, currently, XmlSerializer doesn't deserialize the class properly - it just skips over any Foo element with the JezNamespace xmlns set. I have to set ALL the child elements to have that xmlns.
What I'd like to get to is 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 have XmlSerializer be able to deserialize that properly into a List. Any ideas how I can get it doing this?
Your code has two attributes on Foo
that, so far as I can tell, you've put there to try to associate a 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 in your scenario Foo
is not a root element. The second one doesn't quite do what you probably think it does - the namespace in it is a namespace of an XSD type, not namespace of an element itself.
To specify name and namespace of the element, you do instead need to use XmlArrayItemAttribute
on the List<Foo>
property of a parent class (oh, and you will need that 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 produce:
<FooParent>
<Foos>
<Foo xmlns="http://schemas.datacontract.org/2004/07/JezNamespace">
<Field1>hello</Field1>
<Field2>world</Field2>
</Foo>
...
Alternatively, if you do not want that Foos
intermediate element at all, you can replace XmlArrayItem
in code above 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>
链接地址: http://www.djcxy.com/p/54902.html