Cannot XMLSerialize Business ObjectCannot XMLSerialize Business Object
Old forum URL: forums.lhotka.net/forums/t/1506.aspx
swegele posted on Monday, October 16, 2006
USing CSLA 1.5 - I Get this error trying very simple XMLSerialize.
System.InvalidOperationException: To be XML serializable, types which inherit from ICollection must have an implementation of Add(CSLA.BrokenRules+Rule) at all levels of their inheritance hierarchy. CSLA.BrokenRules+RulesCollection does not implement Add(CSLA.BrokenRules+Rule)
Any ideas?
Sean
JoeFallon1 replied on Monday, October 16, 2006
Rocky has mentioned that the XMLSerializer is woeful compared to the Binary Serializer and will not work on CSLA BOs.
You can search for more info - bottom line is you have to write some non-trivial code if you want to serialize to XML.
Joe
RockfordLhotka replied on Monday, October 16, 2006
The XmlSerializer has some serious limitations on what types it can serialize. Any serious OO model will likely use some of these "off-limits" types, and that includes CSLA itself as well.
Remember, the XmlSerializer is designed to support the SOAP standard for interoperability. To do this, they sacrificed functionality: it is the lowest-common-denominator effect.
The end result, is that the XmlSerializer is only really useful for serializing data transfer object (DTO) graphs, and even then you must be very careful about what types you use for collections or lists. It is a bit better in .NET 2.0 than 1.1, but I still sometimes find it challenging to express my data the way I'd like.
If you look in Chapter 10 in the 1.x book (or 11 in the 2005 book) you'll see that I formally define DTOs to expose through web services; copying the data into and out of the business objects in the asmx code. The reason for this addresses your problem as well: web services use the XmlSerializer...
For those who are interested, the problem doesn't go away with WCF. The new WCF serialization only supports one data contract per object/class, forcing you to choose whether to support external XML serialization, or support for mobile objects. For typical business objects in CSLA, you'll need to go with the mobile object support, or lose the data portal, cloning and n-level undo. The end result is that you'll still need to formally define DTOs for external data exchange. In my view, this is good anyway, because architecturally it is the right approach - regardless of the technology.
SonOfPirate replied on Tuesday, October 17, 2006
If you delve into some of the more popular development suites or toolkits out there, you will find that many have implemented their own custom XmlSerializers to address the litany of shortcomings in the framework-supplied class. Here's a brief list, reproduced from the documentation, of the System.Xml.Serialization.XmlSerializer's short-comings:
- Only works with Public types (protected – not. Internal? - never tried)
- Must have a default parameter-less constructor (does not have to be public)
- No security checks can be performed during deserialization
- Properties must be read/write (and public!)
- Properties cannot return interfaces (won’t know the type to create when deserializing). Abstract base classes are okay.
- No multi-dimensional arrays
- Object graphs cannot contains circular references
- Object references will be serialized each time they are encountered (resulting in multiple instances on deserialization instead of the expected behavior).
- Collections must NOT implement IDictionary
- Base classes should use the XmlIncludeAttribute to list derived classes (when known). This allows the derived class to be serialized for properties with base class return types. Can also apply XmlElement to the property itself (this will accommodate overridden classes outside of the original assembly).
- A collection’s properties are ignored.
- Collections must implement ISerializable to be serializable. Requires foreach to write (serialize) and Add(T) to read (deserialize).
Of these, the requirement to have public read/write properties and public Add methods in collections (versus explicit interface implementations) seem to cause the most headaches and are two of the factors that led me to develop my own XmlSerializer as well.
Keep in mind that this can be a daunting task and should not be taken lightly. There are quite a few attributes and interfaces, etc. that all have to be accounted for. But, if these limitations stand in your way, and you really have to be able to serialize to Xml, then creating your own serializer may be the only way to accomplish your goal.
In our case, our custom serializer allows protected and private set accessors on properties, serializes/deserializes a collection's properties and serializes Dictionaries, Stacks and Queues.
Copyright (c) Marimer LLC