I have a class decorated for XML serialization like so:
[XmlRoot(ElementName = "XXX", Namespace = "http://www.example.com/Schemas/xxx/2011/11")]
public class Xxx<T> where T: Shipment
{
[XmlAttribute("version")]
public string Version = "1.1";
public T Shipment { get; set; }
public Xxx(string dataTargetType)
{
Shipment = (T)Activator.CreateInstance(typeof(T));
Shipment.DataContext = new DataContext
{
DataTargetCollection = new DataTargetCollection
{
DataTarget = new DataTarget
{
Type = dataTargetType
}
}
};
}
}
[XmlType("Shipment")]
public class Shipment
{
public DataContext DataContext { get; set; }
}
When serialized it is outputting the following XML:
<?xml version="1.0" encoding="utf-8"?>
<XXX xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Shipment xmlns="http://www.example.com/Schemas/xxx/2011/11">
<DataContext>
<DataTargetCollection>
<DataTarget>
<Type>WarehouseOrder</Type>
</DataTarget>
</DataTargetCollection>
</DataContext>
</Shipment>
</XXX>
Why is the xmlns namespace attribute being added to the Shipment
node rather than the root XXX
node?
Example of it in use being inherited and serialized: (contrived example while working out serialization issues)
public class XxxVariation: Xxx<Shipment>
{
public const string DataTargetType = "Something";
public XxxVariation() : base(DataTargetType) {}
}
public async Task<string> CreateXxxVariationAsync(string todo)
{
var request = new XxxVariation();
string xmlRequest = SerializeRequest(request);
return await PostRequestAsync(xmlRequest);
}
private static string SerializeRequest<T>(T request)
{
using (var stream = new MemoryStream())
{
var serializer = new XmlSerializer(typeof(T));
serializer.Serialize(XmlWriter.Create(stream), request);
using (var reader = new StreamReader(stream))
{
stream.Seek(0, SeekOrigin.Begin);
string xml = reader.ReadToEnd();
return xml;
}
}
}
Based on the fact that Xxx<T>
doesn't have a public parameterless constructor, I suspect what you actually have is something like:
public class FooXxx : Xxx<Foo> {
public FooXxx() : base("abc") { }
}
and that you are serializing the FooXxx
instance, and using typeof(FooXxx)
when creating the XmlSerializer
. That's... OK I guess, and in theory XmlRootAttribute
is inheritable, but I suspect that the attribute inspection code is explicitly using the "only on the declared type, not inherited" option when checking for attributes. Because of this, it seems that you need to add the attribute again on FooXxx
:
[XmlRoot(ElementName = "XXX", Namespace = "http://www.example.com/Schemas/xxx/2011/11")]
public class FooXxx : Xxx<Foo> {
public FooXxx() : base("abc") { }
}
Note: I've had to infer a lot here; if this doesn't help, please post the actual code you're using to serialize, including your XmlSerializer
initialization, and showing the creation of the object you pass into the serializer.