I'm trying to create an XmlSerializer that serialize and deserializes derived types properly. Please take a look at the code below. Any assistance in using XmlAttributeOverrides ad extra types to create proper XmlSerializer and serialize an instance of GetVehicleResponse with VehicleObject as "SUV" object is greatly appreciated.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Serialization;
using InteractiveSoftworks.Framework.Xml;
using System.IO;
namespace DowncastTest
{
[XmlType(Namespace="urn:Test/Service")]
public class GetVehicleResponse
{
[XmlElement(IsNullable=true, Namespace="urn:Test")]
public Vehicle VehicleObject;
}
[XmlType( Namespace = "urn:test" )]
public class Vehicle
{
public string Model;
public string Number { get; set; }
}
public class Car : Vehicle
{
public int Doors { get; set; }
}
public class SUV : Car
{
public int Engines { get; set; }
}
public class MotorCycle : Vehicle
{
public int Seats { get; set; }
}
public class SportsBike : MotorCycle
{
public int Mirrors { get; set; }
}
public class Program
{
static void Main( string[] args )
{
XmlAttributeOverrides overrides = new XmlAttributeOverrides();
CreateAttributeOverrides( typeof( Car ), "urn:Test", overrides );
CreateAttributeOverrides( typeof( SUV ), "urn:Test", overrides );
CreateAttributeOverrides( typeof( MotorCycle ), "urn:Test", overrides );
CreateAttributeOverrides( typeof( SportsBike ), "urn:Test", overrides );
Type[] extraTypes = new Type[] { typeof( Car ), typeof( SUV ), typeof( MotorCycle ), typeof( SportsBike ) };
XmlSerializer xs = new XmlSerializer( typeof( GetVehicleResponse ), overrides, extraTypes, new XmlRootAttribute() { ElementName = "GetVehicleResponse", Namespace = "urn:Test" }, "urn:Test" );
MemoryStream ms = new MemoryStream();
xs.Serialize( ms, new GetVehicleResponse() { VehicleObject = new SUV() { Number = "AP29", Model = "2011", Doors = 4, Engines = 2 } } );
string s = Encoding.UTF8.GetString( ms.GetBuffer() );
Console.WriteLine( s );
Console.WriteLine( "Done..." );
Console.ReadKey();
}
internal static void CreateAttributeOverrides( Type type, string projectNamespace, XmlAttributeOverrides overrides )
{
// redirect the type if no explicit XmlAttributeType namespace has been provided
//
XmlAttributes typeAttributes = new XmlAttributes( type );
XmlTypeAttribute typeAttribute = null;
if ( typeAttributes.XmlType != null ) // inherit existing methodType attributes if any
{
if ( string.IsNullOrEmpty(typeAttributes.XmlType.Namespace) ) // only set the namespace if it isn't already defined
{
typeAttribute = typeAttributes.XmlType;
typeAttribute.Namespace = projectNamespace;
}
}
else
{
string rootNamespace = string.Empty;
// if type defined Xml Root Attributes then get the namespace and add to type attributes
//
if ( typeAttributes.XmlRoot != null )
rootNamespace = typeAttributes.XmlRoot.Namespace;
if ( string.IsNullOrEmpty( rootNamespace ) )
rootNamespace = projectNamespace;
typeAttribute = new XmlTypeAttribute() { Namespace = rootNamespace };
}
if ( typeAttribute != null )
overrides.Add( type, new XmlAttributes() { XmlType = typeAttribute } ); // use a fresh XmlAttributes as we only want to globally override XmlTypeAttribute
}
}
}