Announcement

Collapse
No announcement yet.

Support for JSON Type Converters or alternative way to perform custom deserialisation

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Support for JSON Type Converters or alternative way to perform custom deserialisation

    The Json.Serialize and Json.Deserialize method in Bridge 16 look really good and it's helpful having the JsonSettings options (so that things like "$type" can be injected by enabling "TypeNameHandling") but I have some types (in particular the "NonNullList") that serialise fine (because it implements IEnumerable) but need some custom code in order to be deserialised*.

    * (Update: Sorry, this wasn't very clear - with JSON.NET, because NonNullList<T> implements IEnumerable<T> then it will be serialised into a JSON array but would then require some special deserialisation logic.. however, Bridge won't serialise it because it doesn't implement [Reflectable])

    With JSON.NET, I can specify additional Converters for a JsonSerializer to use (where each converter can add special handling for particular types) or (iirc) I can implement ISerializable and add custom behaviour that way.

    Bridge doesn't appear to support either of these and I wondered if you had any plans to support either or both or something else that I could use. In an ideal world, I would use types like NonNullList on the server side (in .NET code) and use the same type in Bridge code (there would be different projects built for the server and client but classes such as NonNullList could be shared using a shared project, perhaps) and use JSON.NET and Bridge serialisation / deserialisation to pass data back and forth. In order to do this, though, I need a way to provide "hints" to the (de)serialisation logic one way or another.

    One alternative is to resort to translating to and from a set of "safe to serialise" types before sending information over the wire but this would likely lead me to having to write a lot of these types (and it would either have to be code gen'd or be written by hand; which would make it quite easy to make silly mistakes with).

    I wondered if you had any thoughts about this sort of use case?
    Last edited by ProductiveRage; 2017-05-17 @ 09:18 AM.

  • #2
    DanTup mentioned this article as being a nice summary of custom reading and writing:
    (though it concentrates more on using attributes to specify custom serialisation logic for types while examples that I had in mind configured JsonSerializer instances with any required custom serialiser).

    Comment


    • #3
      Any thoughts on this? The Bridge 16 changes around serialisation are great but they're not quite sufficient for some use cases that we have.

      The ideal would be for the JsonSerializerSettings to support the "Converters" property (an IList of JsonConverter) but I appreciate that that could be quite a lot of work - not only do the type converters need to be considered in the Serialize / Deserialize implementations but the JsonReader and JsonrWriter classes would have to be implemented to support the JsonConverter methods -

      bool CanConvert(Type objectType);
      object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer);
      void WriteJson(JsonWriter writer, object value, JsonSerializer serializer);
      However, something like this would be really helpful. Would you consider simpler-to-implement versions, such as

      bool CanConvert(Type objectType);
      object ReadJson(Type objectType, object existingValue, JsonSerializer serializer);
      void WriteJson(object value, JsonSerializer serializer);
      .. or would you rather do nothing at this point until you can implement something that matches JSON.NET's interface precisely?

      Comment


      • #4
        Hi ProductiveRage,

        Ultimately our goal is to compile the original Newtonsoft.Json source code using Bridge. This should ensure perfect (or near to perfect) compatibility and portability of Newtonsoft.Json usage across native .NET and Bridge.NET compiled apps.

        At this point, that goal is a bit far off, but we are rapidly making progress.

        As an initial step towards fully supporting the Newtonsoft.Json API, as of Bridge 16.0.0-beta2, we are removing the Bridge.Json API and have moved all Json Serialization/Deserialization responsibilities into a new Bridge.Newtonsoft.Json package.

        The first priority with Bridge.Newtonsoft.Json was to ensure all functionality from Bridge.Json was supported, but doing so by implementing partial support for the Newtonsoft.Json API. We wanted to ensure any existing Bridge.Json API usage could be easily ported to the new Bridge.Newtonsoft.Json package, and reproduce the expected result from the native Json.NET API.

        The Bridge.Newtonsoft.Json project README.md documents exactly what is supported. If a Json.NET feature is missing from the README, then it is not supported by Bridge.Newtonsoft.Json. Only the classes and members listed in the README are supported.

        Unfortunately, JsonConverter classes are not currently supported.

        To enable easy testing, the Bridge.Newtonsoft.Json package has also been added to https://dev.deck.net and a basic SerializeObject and DeserializeObject sample has been included.

        https://dev.deck.net/newtonsoft.json

        public class Program
        {
            public static void Main()
            {
                Product product = new Product();
        
                product.Name = "Apple";
                product.ExpiryDate = new DateTime(2008, 12, 28);
                product.Price = 3.99M;
                product.Sizes = new string[] { "Small", "Medium", "Large" };
        
                string output = JsonConvert.SerializeObject(product, Formatting.Indented);
        
                // Write the json string
                Console.WriteLine(output);
        
                // Deserialize the json back into a real Product
                Product deserializedProduct = JsonConvert.DeserializeObject<Product>(output);
        
                // Write the properties
                Console.WriteLine(deserializedProduct.Name);
                Console.WriteLine(deserializedProduct.ExpiryDate);
                Console.WriteLine(deserializedProduct.Price);
                Console.WriteLine(deserializedProduct.Sizes);
            }
        }
        
        public class Product
        {
            public string Name { get; set; }
        
            public DateTime ExpiryDate { get; set; }
        
            public decimal Price { get; set; }
        
            public string[] Sizes { get; set; }
        }
        The above Deck also includes the new feature in Bridge 16.0.0-beta2 where Reflection metadata is automatically included, see Issue #2732. Applying the [Reflectable] attribute to a class is not longer required.

        As you mentioned, supporting JsonConverter requires implementing JsonWriter, which requires implementing StringWriter, which requires implementing support for much of the System.IO namespace in Bridge. It's going to take a while until this is possible.

        New functionality is not likely to be added to Bridge.Newtonsoft.Json until we can start compiling the original Json.NET source code. We will fix Defects and will review Feature Requests on a case-by-case basis, but our priority will be focused on adding as support to Bridge to enable compilation of the original Json.NET source.

        That likely means JsonConverter will have to wait.

        Hope this helps.

        Comment


        • #5
          While I'd have loved you to say that full or approximate JsonConverter is coming soon, it's also very helpful to know one way or the other - so thanks for the info!

          Comment

          Working...
          X