0

I am using .Net core 2, Newtonsoft.JSON 10.0.3 and a MySql with JSON column. The issue i think is because the json column type orders the elements for efficiency, it moves the "$type" out of position zero, which causes the de-serialization to fail.

using the below serializer setting during serialization:

var jsonSetting = new JsonSerializerSettings() { TypeNameHandling = TypeNameHandling.All, TypeNameAssemblyFormatHandling = TypeNameAssemblyFormatHandling.Simple };

yeilds :

{"$type": "ConsoleApplication.TestItem, ConsoleApplication","id": "1a58830b-addc-48a9-a6a9-358d35d2132e", "name": "Tom Hanks",  "description": null}

This works when using the string in a deserialization call.

However, when pulling the data from a JSON column:

{"id": "1a58830b-addc-48a9-a6a9-358d35d2132e", "name": "Tom Hanks", "$type": "ConsoleApplication.TestItem, ConsoleApplication", "description": null}

This causes the deserialization to fail.

below is an example. Does anyone have an idea of how to address this? (besides keeping a TEXT/BLOB field containing the raw json)

using System;
using System.Collections.Generic;
using Newtonsoft.Json;

namespace TestConsoleApplication
{
    class Program
    {
        static void Main(string[] args)
        {
            var jsonSetting = new JsonSerializerSettings() { TypeNameHandling = TypeNameHandling.All, TypeNameAssemblyFormatHandling = TypeNameAssemblyFormatHandling.Simple };

            // serializing these out ahead of time yeilds these string
            //
            string serializedGoodActor = "{\"$type\":\"TestConsoleApplication.GoodActor, TestConsoleApplication\",\"Name\":\"Marlon Brando\",\"BestMovie\":\"The Godfather\"}";
            string serializedBadActor = "{\"$type\":\"TestConsoleApplication.BadActor, TestConsoleApplication\",\"Name\":\"Tracy Morgan\",\"BestMovie\":\"Cop Out\"}";

            //deserialization works fine
            //
            var goodActorObj = JsonConvert.DeserializeObject<IActors>(serializedGoodActor, jsonSetting);
            var badActorObj = JsonConvert.DeserializeObject<IActors>(serializedBadActor, jsonSetting);


            try
            {
                //this is how it would get read from a mysql JSON column (note the location of type)
                //
                string mySqlJsonValue = "{\"BestMovie\":\"The Godfather\",\"$type\":\"TestConsoleApplication.GoodActor, TestConsoleApplication\",\"Name\":\"Marlon Brando\"}";
                var mySqlGoodActorObj = JsonConvert.DeserializeObject<IActors>(mySqlJsonValue, jsonSetting);
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex);
            }

            Console.ReadLine();
        }
    }


    public interface IActors
    {
        string Name { set; get; }   
    }

    public class BadActor : IActors
    {
        public string Name { set; get; }
        public string WorstMovie { set; get; }
    }

    public class GoodActor : IActors
    {
        public string Name { set; get; }
        public string BestMovie { set; get; }
    }

}

The error is misleading at best, but that is entirely another issue.

Newtonsoft.Json.JsonSerializationException: Could not create an instance of type TestConsoleApplication.IActors. Type is an interface or abstract class and cannot be instantiated. Path 'BestMovie', line 1, position 13.
  • Looks like a duplicate of [Newtonsoft JSON.net deserialization error where fields in JSON change order](https://stackoverflow.com/q/29493292/3744182). Solution is to set [`JsonSerializerSettings.MetadataPropertyHandling = MetadataPropertyHandling.ReadAhead`](http://www.newtonsoft.com/json/help/html/P_Newtonsoft_Json_JsonSerializerSettings_MetadataPropertyHandling.htm). – dbc Feb 06 '18 at 00:53
  • Hand-serializing JSON is never a good sign. Don't you have an encoder for that? – tadman Feb 06 '18 at 00:53
  • It was just for example purposes. – AnandPatel83 Feb 06 '18 at 01:40

0 Answers0