Thanks for all the suggestions guys. I finally figured out two things:
1) I needed to remove the XmlArray and XmlArrayItem attributes from the property. 2) I needed to add the set accessor to the property. It seems that if you do not have a set accessor, you need the XmlArray and/or the XmlArrayItem attributes to tell the serializer what to do with itself; and if you implement custom serialization that you can't use them. I'd always get an exception when the property was read stating that "[property] could not be reflected". I'm not sure what that means, but nevertheless things are working good now. I have a Serialize() method built into the base business object so any business object will serialize itself. I just used that method inside the loop that writes out the Xml. Writing the ReadXml method was a bit tougher but I got it to work as well. I can now serialize any removed "trash" items and reconstitute them as well. On 5/16/07, Ron Young <[EMAIL PROTECTED]> wrote:
Just to add a bit to that, the following code writes out the Person->Documents->Document xml structure: //CollectionBase<T> class void WriteXml(XmlWriter writer) { foreach (T item in this) { writer.WriteStartElement(item.GetType().Name); foreach (FieldInfo field in item.GetType().GetFields()) { writer.WriteStartElement(field.Name); writer.WriteValue(field.GetValue(item).ToString()); writer.WriteEndElement(); } writer.WriteEndElement(); } } I suppose the dilemma is choosing whether to serialize field or properties of the class that derives from ItemBase as the Document class does. Ron -----Original Message----- From: Discussion of advanced .NET topics. [mailto:[EMAIL PROTECTED] On Behalf Of Ron Young Sent: Wednesday, May 16, 2007 12:47 PM To: ADVANCED-DOTNET@DISCUSS.DEVELOP.COM Subject: Re: [ADVANCED-DOTNET] Xml Serialization with Collections If you add a setter for the Person.Documents property, you'll get the exception thrown at CollectionBase<T>.WriteXml. If you then comment out the code in CollectionBase<T>.WriteXml, you'll then get the following output, <Person> <ID>a23323...</ID> <Documents /> </Person> Which I believe is a bit closer to where you want to be. Ron -----Original Message----- From: Discussion of advanced .NET topics. [mailto:[EMAIL PROTECTED] On Behalf Of Mike Andrews Sent: Wednesday, May 16, 2007 10:06 AM To: ADVANCED-DOTNET@DISCUSS.DEVELOP.COM Subject: [ADVANCED-DOTNET] Xml Serialization with Collections I've got an issue with which I would appreciate some assistance in its resolution. I've got a complex business object that used for a website. The website programmers need to serialize the object to viewstate. This process works quite well as it stands now. Now an issue has arisen that requires "removed" items (in one of the collection objects attached to the business object via a property) to be serialized and then restored in order to allow for canceling the removal (delete). What I've run into so far is that if I implement the IXmlSerializable interface on the collection itself, then serialize the complex business object, the property that did serialize now won't serialize at all. Also, when putting a breakpoint in the IXmlSerializable interface code, it does not break. This has become very frustrating. I've listed some sample code below that demonstrates this behavior. As you can see, the exceptions that are thrown in the serialization code are not thrown. Any suggestions would be appreciated. Thanks, Mike class Program { static void Main(string[] args) { Person p = new Person(); p.ID = Guid.NewGuid(); Document d = new Document(); d.Description = "Test"; d.ID = Guid.NewGuid(); p.Documents.Add(d); //The documents will not be serialized! string xml = p.Serialize(); } } public abstract class ItemBase { public Guid ID; /// <summary> /// Returns the xml respresentation of this object. /// </summary> /// <returns></returns> public string Serialize() { StringBuilder sb = new StringBuilder(); XmlSerializer xs = new XmlSerializer(this.GetType()); XmlSerializerNamespaces nameSpaces = new XmlSerializerNamespaces(); nameSpaces.Add("", ""); XmlWriterSettings settings = new XmlWriterSettings(); settings.Indent = true; settings.OmitXmlDeclaration = true; settings.Encoding = Encoding.UTF8; XmlWriter writer = XmlWriter.Create(sb, settings); xs.Serialize(writer, this, nameSpaces); return sb.ToString(); } } public abstract class CollectionBase<ItemType> : List<ItemType>, IXmlSerializable where ItemType : ItemBase { #region IXmlSerializable Members System.Xml.Schema.XmlSchema System.Xml.Serialization.IXmlSerializable.GetSchema() { return new System.Xml.Schema.XmlSchema(); } void System.Xml.Serialization.IXmlSerializable.ReadXml( System.Xml.XmlReader reader) { throw new Exception("The method or operation is not implemented."); } void System.Xml.Serialization.IXmlSerializable.WriteXml( System.Xml.XmlWriter writer) { throw new Exception("The method or operation is not implemented."); } #endregion } public class Person: ItemBase { public string Name; private DocumentCollection _documents; [XmlArray("Documents"), XmlArrayItem("Document")] public DocumentCollection Documents { get { if (_documents == null) { _documents = new DocumentCollection(); } return _documents; } } } public class Document : ItemBase { public string Description; } public class DocumentCollection : CollectionBase<Document> { } =================================== This list is hosted by DevelopMentorR http://www.develop.com View archives and manage your subscription(s) at http://discuss.develop.com =================================== This list is hosted by DevelopMentor. http://www.develop.com View archives and manage your subscription(s) at http://discuss.develop.com =================================== This list is hosted by DevelopMentor(r) http://www.develop.com View archives and manage your subscription(s) at http://discuss.develop.com
=================================== This list is hosted by DevelopMentorĀ® http://www.develop.com View archives and manage your subscription(s) at http://discuss.develop.com