我正在尝试创建一个XmlSerializer,它可以正确地序列化和反序列化派生类型。请看下面的代码。任何帮助使用XmlAttributeOverrides广告额外类型来创建正确的XmlSerializer并将VehicleObject的实例序列化为“SUV”对象的GetVehicleResponse实例非常感谢。
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
}
}
}
答案 0 :(得分:0)
我认为您正在寻找XmlIncludeAttribute
答案 1 :(得分:0)
作为替代方法,您可以使用a form of the XmlSerializer that supports an extra types parameter that you can use to specify derived types: 来自doc:
您还可以使用extraTypes参数指定从基类派生的类型。
这在我的经验中运作良好,但并不适用于所有情况,因为您需要准备好解决Microsoft实施中的潜在问题。有关详细信息,请参阅XmlSerializer doc中有关动态生成的装配的部分。