I have a generic type Foo1 which is basically a container with some metadata and a generic list. When I serialize that type, it gets the name "Foo1Of" + TypeParameterName.
public class Foo1<T>
{
public string Name { get; set; } = string.Empty;
public List<T> List { get; set; } = new List<T>();
}
[TestMethod]
public void SerializeFoo1()
{
Foo1<string> foo = new Foo1<string>
{
Name = "Foo1",
List =
{
"Bar",
"Baz"
}
};
XmlSerializer s = new XmlSerializer(foo.GetType());
StringBuilder sb = new StringBuilder();
XmlWriter w = XmlWriter.Create(sb);
s.Serialize(w, foo);
Console.WriteLine(sb.ToString());
}
This is the old version and returns:
<?xml version="1.0" encoding="utf-16"?>
<Foo1OfString xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Name>Foo1</Name>
<List><string>Bar</string><string>Baz</string></List>
</Foo1OfString>
To access the internal list more directly I implemented IEnumerable, IEnumerable and an Add(...) method.
public class Foo2<T> : IEnumerable<T>, IEnumerable
{
public string Name { get; set; } = string.Empty;
public List<T> List { get; set; } = new List<T>();
public void Add(T item)
{
List.Add(item);
}
public IEnumerator<T> GetEnumerator()
{
return List.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return List.GetEnumerator();
}
}
[TestMethod]
public void SerializeFoo2()
{
Foo2<string> foo = new Foo2<string>
{
Name = "Foo2",
List =
{
"Bar",
"Baz"
}
};
XmlSerializer s = new XmlSerializer(foo.GetType());
StringBuilder sb = new StringBuilder();
XmlWriter w = XmlWriter.Create(sb);
s.Serialize(w, foo);
Console.WriteLine(sb.ToString());
}
After doing that, XML Serialization behaves very strange:
<?xml version="1.0" encoding="utf-16"?>
<ArrayOfString xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<string>Bar</string><string>Baz</string>
</ArrayOfString>
The name becomes "ArrayOf" + TypeParameterName and the property "Name" vanishes. The XmlSerializer seems to think, that my custom type is an array. Is there a way to change this behaviour which means to be able to implement the interfaces and Add(...) but get the old XML serialization?
This is default behavior of XmlSerializer as you are implementing IEnumerable<T> interface. Due to IEnumerable<string> type, XmlSerializer thinks it is a collection/array of string.
If you must implemented IEnumerable<T>, then one way to overcome this default behavior is to implement custom serialization. Implement IXmlSerializable for your Foo1<T>. You can then customize the Xml graph as you wish, and return your desired Name and List. XmlSerializer will then your custom implementation.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With