C#
ASP.NET
VSTO
XmlSerializableBase Class
This class was designed as a wrapper for XML schema-generated classes ( eg. via xsd.exe or XSDObjectGen ).
public abstract class XmlSerializableBase : IXmlSerializable { #region Contract //an XSD-generated class protected abstract object DataObject { get; set; } //necessary because the DataObject may be null, //so using 'typeof' with XmlSerializer wouldn't work public abstract Type DataObjectType { get; } #endregion #region Copy-Constructor protected XmlSerializableBase( XmlSerializableBase original ) { using ( MemoryStream stream = new MemoryStream() ) { original.WriteXml( stream ); stream.Seek( 0, SeekOrigin.Begin ); this.ReadXml( stream ); } } #endregion #region ToString() Override public override string ToString() { StringBuilder sb = new StringBuilder(); StringWriter writer = new StringWriter( sb ); this.WriteXml( writer ); return sb.ToString(); } #endregion #region IXmlSerializable Members public virtual void WriteXml( XmlWriter writer ) { XmlSerializer serializer; serializer = new XmlSerializer( this.DataObjectType ); serializer.Serialize( writer, this.DataObject ); } public virtual void ReadXml( XmlReader reader ) { XmlSerializer serializer; serializer = new XmlSerializer( this.DataObjectType ); this.DataObject = serializer.Deserialize( reader ); } public virtual XmlSchema GetSchema() { return null; } #endregion #region Additional Read/Write Xml public virtual void ReadXml( string filename ) { using (StreamReader reader = new StreamReader( filename )) { this.ReadXml( reader ); } } public virtual void ReadXml( TextReader reader ) { XmlSerializer serializer; serializer = new XmlSerializer( this.DataObjectType ); this.DataObject = serializer.Deserialize( reader ); } public virtual void ReadXml( Stream stream ) { XmlSerializer serializer; serializer = new XmlSerializer( this.DataObjectType ); this.DataObject = serializer.Deserialize( stream ); } public virtual void WriteXml( Stream stream ) { XmlSerializer serializer; serializer = new XmlSerializer( this.DataObjectType ); serializer.Serialize( stream, this.DataObject); } public virtual void WriteXml( TextWriter writer ) { XmlSerializer serializer; serializer = new XmlSerializer( this.DataObjectType ); serializer.Serialize( writer, this.DataObject ); } public virtual void WriteXml( string filename ) { using (StreamWriter writer = new StreamWriter( filename )) { this.WriteXml( writer ); } } #endregion #region Read/Write Encrypted public virtual void WriteEncryptedXml( string filename, ICryptoTransform transform ) { CryptoStream cryptstream; FileStream outfile; outfile = new FileStream( filename, FileMode.OpenOrCreate, FileAccess.Write ); cryptstream = new CryptoStream( outfile, transform, CryptoStreamMode.Write ); this.WriteXml( cryptstream ); cryptstream.Close(); outfile.Close(); } public virtual void WriteEncryptedXml( string filename, byte[] rijnKey, byte[] rijnIV ) { SymmetricAlgorithm rijndael; ICryptoTransform transform; rijndael = SymmetricAlgorithm.Create(); transform = rijndael.CreateEncryptor( rijnKey, rijnIV ); this.WriteEncryptedXml( filename, transform ); } public virtual void ReadEncryptedXml( string filename, ICryptoTransform transform ) { CryptoStream cryptstream; FileStream infile; infile = new FileStream( filename, FileMode.Open, FileAccess.Read ); cryptstream = new CryptoStream( infile, transform, CryptoStreamMode.Read ); this.ReadXml( cryptstream ); cryptstream.Close(); infile.Close(); } public virtual void ReadEncryptedXml( string filename, byte[] rijnKey, byte[] rijnIV ) { SymmetricAlgorithm rijndael; ICryptoTransform transform; rijndael = SymmetricAlgorithm.Create(); transform = rijndael.CreateDecryptor( rijnKey, rijnIV ); this.ReadEncryptedXml( filename, transform ); } #endregion }
[TestFixture] public class TestXmlSerializableBase { Contact contact; public TestXmlSerializableBase() { contact = new Contact(); contact.FirstName = "Jimmy"; contact.LastName = "Joe"; contact.Address.BuildingNumber = "222"; contact.Address.StreetName = "HighLow Street"; contact.Address.AdditionalAddressLines.Add( "Piccadilly" ); contact.Address.AdditionalAddressLines.Add( "Leicester Square" ); Debug.Write( "xml: " + contact.ToString() ); } [Test] public void TestToStringMethod() { XmlDocument doc; XmlNode node; doc = new XmlDocument(); doc.LoadXml( contact.ToString() ); node = doc.SelectSingleNode( "/Contact/FirstName" ); Assert.IsTrue( contact.FirstName == node.InnerText ); node = doc.SelectSingleNode( "/Contact/LastName" ); Assert.IsTrue( contact.LastName == node.InnerText ); } [Test] public void TestCloneMethod() { Contact copy = contact.Clone(); Assert.IsNotNull( copy ); Assert.IsTrue( contact.FirstName == copy.FirstName ); copy.FirstName = "Billy"; Assert.IsFalse( contact.FirstName == copy.FirstName ); } [Test] public void TestReadWriteEncryptedXml() { byte[] key; byte[] iv; SymmetricAlgorithm rijndael; string filename; Contact decryptedContact; rijndael = SymmetricAlgorithm.Create(); rijndael.GenerateIV(); rijndael.GenerateKey(); key = rijndael.Key; iv = rijndael.IV; filename = Path.GetTempFileName(); this.contact.WriteEncryptedXml( filename, key, iv ); Assert.IsTrue( File.Exists( filename ) ); //now try to 'rehydrate' the encrypted file decryptedContact = new Contact(); decryptedContact.ReadEncryptedXml( filename, key, iv ); Assert.IsTrue( contact.FirstName == decryptedContact.FirstName ); Assert.IsTrue( contact.LastName == decryptedContact.LastName ); } }
public class Contact : XmlSerializableBase { private ContactData __contactData = new ContactData(); public Contact() {} protected Contact( Contact original ) : base(original) {} protected override object DataObject { get { return __contactData; } set {__contactData = (ContactData) value; } } public override Type DataObjectType { get {return typeof( ContactData ); } } public string FirstName { get { return __contactData.FirstName; } set { __contactData.FirstName = value; } } public string LastName { get { return __contactData.LastName; } set { __contactData.LastName = value; } } public AddressDataType Address { get { return __contactData.Address; } } public Contact Clone() { return new Contact( this ); } }
[XmlRoot("Contact"), Serializable] public class ContactData { public ContactData() {} [XmlElement( "FirstName", typeof( string ) )] public string FirstName; [XmlElement( "LastName", typeof( string ) )] public string LastName; [XmlElement( "Address", typeof( AddressDataType ) )] public AddressDataType Address = new AddressDataType(); } [XmlType("AddressDataType"),Serializable] public class AddressDataType { public AddressDataType() {} [XmlElement( "BuildingNumber", typeof( string ) )] public string BuildingNumber; [XmlElement( "StreetName", typeof( string ) )] public string StreetName; [XmlElement( "AdditionalAddressLine", typeof( string ) )] public ArrayList AdditionalAddressLines = new ArrayList(); [XmlElement( "District", typeof( string ) )] public string District; [XmlElement( "PostalTown", typeof( string ) )] public string PostalTown; [XmlElement( "PostalCode", typeof( string ) )] public string PostalCode; [XmlElement( "Region", typeof( string ) )] public string Region; [XmlElement( "CountrySubEntity", typeof( string ) )] public string CountrySubEntity; [XmlElement( "Country", typeof( string ) )] public string Country; }