I've been reading Keith Pijanowski's article - Enrich Your XML Serialization
With Schema Providers In The .NET Framework - on how to do custom
serialization of objects. Link to the article:
http://msdn.microsoft.com/msdnmag/is...t/default.aspx
Now I'm trying to do the same ting in a more complex scenario, with two
nested classes. The nested class is used in a collection property of the
main class, and I want that collection to be automatically serialized. Here
is a copy of the source without properties and contructors:
namespace MeritAdmin.Cust omer
{
[XmlRoot(Element Name = "applicatio n", IsNullable = false, Namespace =
"http://meritconsulting .no/MovexApplicatio nProperties.xsd ")]
[XmlSchemaProvid er("GetSchemaFi le")]
public class MovexApplicatio nProperties : IXmlSerializabl e
{
public const string ApplicationType = "movex";
public const int Version = 2;
private string _administratorU ser;
private string _administratorP assword;
private string _servicePack;
private string _movexVersion;
private
List<MeritAdmin .Customer.Movex ApplicationProp erties.Environm ent>
_environments = new
List<MeritAdmin .Customer.Movex ApplicationProp erties.Environm ent>();
#region XmlSchema
public static XmlSchemaComple xType GetSchemaFile(X mlSchemaSet
schemaSet)
{
string xsdFile = Directory.GetCu rrentDirectory( ) +
"\\Customer\\Mo vexApplicationP roperties.xsd";
XmlSerializer schemaSerialize r = new
XmlSerializer(t ypeof(XmlSchema ));
XmlSchema schema =
(XmlSchema)sche maSerializer.De serialize(XmlRe ader.Create(xsd File));
schemaSet.Add(s chema);
// Target namespace
string tns =
"http://meritconsulting .no/MovzexApplicati onProperties.xs d";
XmlQualifiedNam e application = new
XmlQualifiedNam e("application" , tns);
XmlSchemaComple xType applicationType =
(XmlSchemaCompl exType)schema.S chemaTypes[application];
return applicationType ;
}
#endregion
#region IXmlSerializabl e Members
public System.Xml.Sche ma.XmlSchema GetSchema()
{
throw new Exception("The method or operation is not
implemented.");
}
public void ReadXml(System. Xml.XmlReader reader)
{
throw new Exception("The method or operation is not
implemented.");
}
public void WriteXml(System .Xml.XmlWriter writer)
{
string ns =
"http://meritconsulting .no/MovexApplicatio nProperties.xsd ";
writer.WriteAtt ributeString("t ype",
MovexApplicatio nProperties.App licationType);
writer.WriteEle mentString("ver sion",
MovexApplicatio nProperties.Ver sion.ToString() );
writer.WriteEle mentString("adm inistratorUser" ,
this.Administra torUser);
writer.WriteEle mentString("adm inistratorPassw ord",
this.Administra torPassword);
writer.WriteEle mentString("ser vicePack", this.ServicePac k);
writer.WriteEle mentString("mov exVersion", this.MovexVersi on);
writer.WriteEle mentString("env ironments", ns, string.Empty);
// This is not the right way to do it
//foreach (Environment environment in this.Environmen ts)
//{
// environment.Wri teXml(writer);
//}
}
#endregion
[XmlRoot(Element Name = "environmen t", IsNullable = true, Namespace =
"http://meritconsulting .no/MovexApplicatio nProperties.xsd ")]
[XmlSchemaProvid er("GetSchemaFi le")]
public class Environment : IXmlSerializabl e
{
private string _name;
private string _portNumber;
#region XmlSchema
public static XmlSchemaComple xType GetSchemaFile(X mlSchemaSet
schemaSet)
{
string xsdFile = Directory.GetCu rrentDirectory( ) +
"\\Customer\\Mo vexApplicationP roperties.xsd";
XmlSerializer schemaSerialize r = new
XmlSerializer(t ypeof(XmlSchema ));
XmlSchema schema =
(XmlSchema)sche maSerializer.De serialize(XmlRe ader.Create(xsd File));
schemaSet.Add(s chema);
// Target namespace
string tns =
"http://meritconsulting .no/MovexApplicatio nProperties.xsd ";
XmlQualifiedNam e environment = new
XmlQualifiedNam e("environment" , tns);
XmlSchemaComple xType environmentType =
(XmlSchemaCompl exType)schema.S chemaTypes[environment];
return environmentType ;
}
#endregion
#region IXmlSerializabl e Members
public XmlSchema GetSchema()
{
throw new Exception("The method or operation is not
implemented.");
}
public void ReadXml(XmlRead er reader)
{
throw new Exception("The method or operation is not
implemented.");
}
public void WriteXml(XmlWri ter writer)
{
string ns =
"http://meritconsulting .no/MovexApplicatio nProperties.xsd ";
writer.WriteEle mentString("nam e", ns, this.Name);
writer.WriteEle mentString("por tNumber", ns,
this.PortNumber );
}
#endregion
}
}
}
And this is how I'm trying to serialize some test objects:
private void Form1_Load(obje ct sender, EventArgs e)
{
MovexApplicatio nProperties movex = new
MovexApplicatio nProperties("te st", "test", "12", "v12Java");
movex.Environme nts.Add(new
MovexApplicatio nProperties.Env ironment("TST", "16800"));
List<TypeextraT ypes = new List<Type>();
extraTypes.Add( new
MovexApplicatio nProperties.Env ironment().GetT ype());
XmlSerializer serializer = new XmlSerializer(m ovex.GetType(),
extraTypes.ToAr ray());
StringWriter stringWriter = new StringWriter();
serializer.Seri alize(stringWri ter, movex);
this.textBox1.T ext = stringWriter.To String();
}
Here is the result:
<?xml version="1.0" encoding="utf-16"?>
<application type="movex"
xmlns="http://meritconsulting .no/MovexApplicatio nProperties.xsd ">
<version>2</version>
<administratorU ser>test</administratorUs er>
<administratorP assword>test</administratorPa ssword>
<servicePack>12 </servicePack>
<movexVersion>v 12Java</movexVersion>
<environments />
</application>
As you can see, the environments tag isn't aware of the contents of the
collection, and the environment doesn't get serialized even though I've
passed the Environment type as extra types to the XmlSerializer. What is the
right way to do this?
---
Eivind