2

I need read/write Json from/to a POCO that is decorated with XmlSerialization attributes. This POCO has been generated from an XSD. It makes extensive use of polymorphism, inheritance, objects, arrays of objects and array of abstract classes. I've already tried JsonFx V2 that looked very promising but unfortunately this is not working well and there is almost no activity for several years now on this open source project.

Any help appreciated.

Update 1 : AFAIK Json.NET does not know how to deal with XmlSerialization attributes.

Update 2 : ServiceStack V3 seems to do the job, but I have at least one issue.

A _type member is added when a property is of type object, which is fine. But there is no such information for an array of object.

Consider the following c# classes :

[System.Xml.Serialization.XmlIncludeAttribute(typeof(adxppostalCode))]
public partial class ADXP : ST
{
  ...
}

and

[System.Xml.Serialization.XmlTypeAttribute(TypeName = "adxp.postalCode"]
public partial class adxppostalCode : ADXP
{
}

If an array of object (object[]) contains an instance of adxppostalCode there is no type information put in the Json at serialization. Consequently it add an instance of the class ADXP to the array at deserialization instead of an instance of adxppostalCode.

I hope this is only a configuration issue, because besides this behavior, it is working well.

Udapte 3 : After some more testing, it appears that Json.NET (at least version 7.0.1 Beta 3) supports the attributes and emit the correct type information for array of objects (namespace and library name has been removed).

"Items": [
              {
                "$type": "adxppostalCode, ....",
                "mediaType": "text/plain",
                "compressionSpecified": false,
                "integrityCheckAlgorithm": 0,
                "representation": 1,
                "Text": [
                  "69110"
                ]
              }
            ]

For an array of abstract class, the correct type is written in the output. At deserialization it tries to create an instance of the base type which is abstract and it fails. For instance :

Json fragment :

"Items": [
          {
            "$type": "IVXB_TS, ...",
            "inclusive": true,
            "value": "20091231"
          }
        ]

Could not create an instance of type QTY. Type is an interface or abstract class and cannot be instantiated.

Class hierarchy :

[System.Xml.Serialization.XmlIncludeAttribute(typeof(IVXB_TS))]
public abstract partial class ANY : object, System.ComponentModel.INotifyPropertyChanged
{
}

[System.Xml.Serialization.XmlIncludeAttribute(typeof(IVXB_TS))]
public abstract partial class QTY : ANY
{
}

[System.Xml.Serialization.XmlIncludeAttribute(typeof(IVXB_TS))]
public partial class TS : QTY
{
}

public partial class IVXB_TS : TS
{
}

The array of abstract class :

[System.Xml.Serialization.XmlElementAttribute("high", typeof(IVXB_TS))]
[System.Xml.Serialization.XmlElementAttribute("low", typeof(IVXB_TS))]
public QTY[] Items
  • 1
    These kind of questions are off-topic on SO. Anyway, take a look at [Json.NET](http://www.newtonsoft.com/json/help/html/ConvertingJSONandXML.htm) – Yuval Itzchakov May 19 '15 at 13:18
  • Which attributes are you talking about exactly? ServiceStack supports DataContract/DataMember attributes. JSON.NET has its own attributes. – Ufuk Hacıoğulları May 19 '15 at 13:38
  • What are you trying to do? Most XmlSerialization attributes are meaningless for Json. There is *no* polymorphism or inheritance in Json and almost everything is either an array of objects or a dictionary. – Panagiotis Kanavos May 19 '15 at 13:38
  • 3
    A common mistake in serialization is trying to use a single model to solve multiple problems. Whenever serializing a general-purpose model gets tricky, your **immediate** response should be: create a DTO that exists *purely* for this serialization format - including the required structure and attributes for the specific serializer. You will save a *lot* of time and sanity by simply creating a second DTO model and mapping between them as needed. – Marc Gravell May 19 '15 at 13:53
  • @UfukHacıoğulları Trying ServiceStack V3 right now. –  May 19 '15 at 14:05
  • @UfukHacıoğulları ServiceStack seems to do the job. See updated question. –  May 19 '15 at 15:14
  • Updating the question title and tags should help. – Ufuk Hacıoğulları May 19 '15 at 15:16
  • @UfukHacıoğulları it seems to be [by design](http://stackoverflow.com/a/15347312/15186) –  May 19 '15 at 15:26
  • @MarcGravell I agree with you, but I have no control over this XSD and I need all the flexibility of the [object model](http://www.hl7.org/implement/standards/product_brief.cfm?product_id=7) I'm using. –  May 20 '15 at 06:47
  • @omatrot You can post your solution as an answer. – Ufuk Hacıoğulları May 20 '15 at 10:39

1 Answers1

0

Well Json.NET 7.0.1 Beta 3 is in fact able to deal with all these cases.

The key takeaway is that the deserializer must be configured for type handling as it was for serialization. I wrongly assumed that the type information available in the json file would be automatically used.

May be an earlier version will do the same.