How to add types information to JSON on serialization?

Pavel Voronin

Angular requires Date objects in many places whereas JSON contains string representation of the date.

I want to add an array of properties which contain date values:

class Foo
{
    public int IntProp {get;set;}
    public DateTime? Prop1 {get;set;}
    public DateTime  Prop2 {get;set;}
    public Bar Bar {set;set;}
}

class Bar
{
    public DateTime Prop {get;set;}
    public IEnumerable<DateTime?> Dates {get;set;} 
}

Foo should then be serialized like this:

{
   "IntProp": 1,
   "Prop1": "...",
   "Prop2": "...",
   "Bar": {
       "Prop": "..."
   },

   "<Dates>": [ "Prop1", "Prop2", "Bar.Prop", "Bar.Dates"]
}

This allows me to automatically convert strings to date objects at the client side without testing every property whether it is convertible to Date like it is described in this question.

I can collect the paths of date properties, but have no idea how to add populated array to the root.

dbc

You could convert to an intermediate JObject and add the property there. For instance, given the following converter:

public class PathLoggingDateTimeConverter : IsoDateTimeConverter
{
    public const string DatePathPropertyName = "<Dates>";

    readonly List<string> paths = new List<string>();

    public override bool CanConvert(Type objectType)
    {
        if (!base.CanConvert(objectType))
            return false;
        // Not for DateTimeOffset
        return objectType == typeof(DateTime) || objectType == typeof(DateTime?);
    }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        base.WriteJson(writer, value, serializer);
        if (value != null)
            paths.Add(writer.Path);
    }

    public IList<string> Paths { get { return paths; } }
}

You can do:

        var root = new Foo
        {
            IntProp = 101,
            Prop1 = DateTime.Today.ToUniversalTime(),
            Prop2 = DateTime.Today.ToUniversalTime(),
            Bar = new Bar
            {
                Prop = DateTime.Today.ToUniversalTime(),
                Dates = new List<DateTime?> { null, DateTime.Today.ToUniversalTime() },
            },
        };

        var converter = new PathLoggingDateTimeConverter();
        var settings = new JsonSerializerSettings { Converters = new[] { converter } };
        var obj = JObject.FromObject(root, JsonSerializer.CreateDefault(settings));
        obj[PathLoggingDateTimeConverter.DatePathPropertyName] = JToken.FromObject(converter.Paths);

        Console.WriteLine(obj);

And the result is:

{
  "IntProp": 101,
  "Prop1": "2016-10-25T04:00:00Z",
  "Prop2": "2016-10-25T04:00:00Z",
  "Bar": {
    "Prop": "2016-10-25T04:00:00Z",
    "Dates": [
      null,
      "2016-10-25T04:00:00Z"
    ]
  },
  "<Dates>": [
    "Prop1",
    "Prop2",
    "Bar.Prop",
    "Bar.Dates[1]"
  ]
}

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

how to add type information in Json serialization in Angular 7

Does Json.NET cache types' serialization information?

JSON serialization for option types

How do I add brackets within JSON serialization?

How to add timezone offset to JSON.NET serialization?

How to add server timezone to localdatetime during JSON serialization?

Send supertype as type information in Kafka JSON Serialization

How to add multiple types of objects to json array?

How to force JSON serialization to include type information for a polymorphic System.Enum member?

F#, Json, WebApi Serialization of Option Types

how to suppress the extra information in boost serialization::archive?

How to replace labels of json array and add information prior to the array

how to add information to json using Python in fast way

Extending Data Types or way to add information

Add root element to json serialization in C#

How to add % information on a treemap?

How to add information to string

Losing type information due to erause, JSON serialization with Jackson/Scalatra

How do I add lexicographical sort in this System.Text.Json serialization way?

Spring REST JSON serialization/deserialization of composite polymorphic types

Handle primitive union types in JSON (de)serialization with Jackson in Java

Simple types JSON serialization in ASP.net Web-api

How is it that json serialization is so much faster than yaml serialization in Python?

how to add model field to object after serialization

How to add to an XML serialization a Class independent tag

Java Object Serialization - How to add member variable?

How to add namespaces to XML before serialization

Jersey serialization/deserialization issue: abstract types can only be instantiated with additional type information

Changing the information before serialization