16. March 2010 12:47
I have been doing a bit of Web code where the state of an object must be persisted per Session, between HttpRequests within an HttpCookie. In the past I have stored data of this type in as an encrypted string of XML in the FormsAuthentication cookie and use XmlSerializer to serialize/de-serialize between the requests and responses, which ahas worked quite nicely. However, in this scenario I decided to persist as encrypted JSON string and use the DataContractJsonSerializer to do the serialization and de-serialization.
The DataContractJsonSerializer works similar to any other serializer, like XmlSerializer, and the code to do so is pretty simple:
However, I quickly ran into an issue while unit testing this code:
System.Runtime.Serialization.SerializationException: Type 'Genesis.Framework.Web.ADAM.Security.AdamPrincipal' with data contract name 'AdamPrincipal:http://schemas.datacontract.org/2004/07/Genesis.Framework.Web.ADAM.Security'is not expected. Add any types not known statically to the list of known types - for example, by using the KnownTypeAttribute attribute or by adding them to the list of known types passed to DataContractSerializer.
The problem is that while it seems rather obvious that the serializer should be able to simple use the interface definition to perform the serialization/de-serialization, this is simple not the case. You have to supply a list of “known types”, which are simply the implementation of the said interface. The serializer uses the known type(s) to determine which data contract to serialize or de-serialize to: it is the target type.
Alternatively, instead of adding a list of known types to the DataContractJsonSerializer constructor like I did above, you can adorn your types with the KnownTypeAttribute, which has the same effect. In this case I chose _not_ to ‘dirty up’ my types with attributes ;)