2

Closed

Polymorphic type conversion issues

description

Hi,

I am having my model declared like:
public class Message : EntityBase
  {
       public Header Header { get; set; }

    /// One to many data blocks.
    /// Derived classes from 'Block' class should be added here for auto serialization-de-serialization by the serializer.
        public List Blocks { get; set; }
  }

  public class Block : EntityBase
  {
  }

  public class IgnitionState : Block
  {
    public bool IsOn { get; set; }
  }

public class Location : Block
  {
    public double Latitude { get; set; }
    public double Longitude { get; set; }
    public bool IsValid { get; set; }
    public double? PrecisionKilometers { get; set; }
  }

  public class AltitudeKilometers : Block
  {
    public double Value { get; set; }
  }
  public class EntityBase
  {
public string Error    
{
get;
}
}
And here is the json schem generated which doesn't include the derived Block types in the schema:
{
"type": "object",
"properties": {
"Messages": {
  "required": true,
  "type": [
    "array",
    "null"
  ],
  "items": {
    "type": [
      "object",
      "null"
    ],
    "properties": {
      "Header": {
        "required": true,
        "type": [
          "object",
          "null"
        ],
        "properties": {
          "Origin": {
            "required": true,
            "type": [
              "object",
              "null"
            ],
            "properties": {
              "Device": {
                "required": true,
                "type": [
                  "object",
                  "null"
                ],
                "properties": {
                  "DeviceId": {
                    "required": true,
                    "type": [
                      "string",
                      "null"
                    ]
                  },
                  "Type": {
                    "required": true,
                    "type": [
                      "string",
                      "null"
                    ]
                  },
                  "Error": {
                    "type": [
                      "string",
                      "null"
                    ]
                  }
                }
              },
              "Asset": {
                "required": true,
                "type": [
                  "object",
                  "null"
                ],
                "properties": {
                  "MakeCode": {
                    "required": true,
                    "type": [
                      "string",
                      "null"
                    ]
                  },
                  "SerialNumber": {
                    "required": true,
                    "type": [
                      "string",
                      "null"
                    ]
                  },
                  "VIN": {
                    "required": true,
                    "type": [
                      "string",
                      "null"
                    ]
                  },
                  "AssetId": {
                    "type": "integer"
                  },
                  "Error": {
                    "type": [
                      "string",
                      "null"
                    ]
                  }
                }
              }
            }
          },
          "TimestampUtc": {
            "required": true,
            "type": "string"
          },
          "ReferenceId": {
            "required": true,
            "type": [
              "string",
              "null"
            ]
          },
          "Error": {
            "type": [
              "string",
              "null"
            ]
          }
        }
      },
      "Blocks": {
        "required": true,
        "type": [
          "array",
          "null"
        ],
        "items": {
          "type": [
            "object",
            "null"
          ],
          "properties": {
            "Error": {
              "type": [
                "string",
                "null"
              ]
            }
          }
        }
      }
    }
  }
}
}
}

Because this i am unable to convert json to .net classes when the json has blocks for derived types .

The sample json looks like as below:
{
"Messages": [
{
  "Header": {
    "Origin": {
      "Device": {
        "DeviceId": "1234",
        "Type": "MTS521"
      },
      "Asset": {
        "MakeCode": "1111",
        "SerialNumber": "1111",
        "VIN": "111",
        "AssetId": 1234
      }
    },
    "TimestampUtc": "2013-01-24T11:11:54.1441045Z",
    "ReferenceId": "12345"
  },
  "Blocks": [
    {
      "Latitude": 10.5,
      "Longitude": 11.5,
      "IsValid": true,
      "PrecisionKilometers": 1.0
    },
    {
      "IsOn": true
    }
  ]
}
]
}

Alternatively i modified my schema as described in the attached file and when i try to validate json validator throws an exception:

Messages[0].Blocks[0].Latitude:Newtonsoft.Json.Schema.JsonSchemaException: Property 'Latitude' has not been defined and the schema does not allow additional properties. Line 22, position 22.

Messages[0].Blocks[0].Longitude:Newtonsoft.Json.Schema.JsonSchemaException: Property 'Longitude' has not been defined and the schema does not allow additional properties. Line 23, position 23.
  var schema = JsonSchema.Parse(rawSchema);

  var messages = new List();
  var reader = new JsonTextReader(new StringReader(json));
  var validatingReaer = new JsonValidatingReader(reader) { Schema = schema };

  validatingReaer.ValidationEventHandler += (o, a) => messages.Add(a.Path + ":" + a.Exception);

  var result = serializer.Deserialize(validatingReaer);

Even i have used JsonConverter to customise the type conversion for polymorphic type converts. Any help is greately appreciated.

file attachments

Closed Jan 30, 2013 at 10:15 AM by JamesNK
The deserializer doesn't know what type should be created for a block.

comments

nikolawannabe wrote Jan 25, 2013 at 8:50 PM

I have the same problem - after upcasting my objects to get rid of things that I don't want to be serialized, JSON.NET still serializes the entire object even though it should not be able to access those properties. Since the child class has properties that can't be serialized, this blows up.

I solved it personally by instantiating a new instance of the parent class object, but this shouldn't be required.