Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JSON.Net Struct Serialization Discrepancy

Tags:

json

c#

json.net

When using JSON.Net to serialize/deserialize structs, a build-in struct type (like System.Drawing.Size) serializes to a string, whereas a custom struct type serializes to a JSON object.

For example:

using System;
using System.Drawing;
using Newtonsoft.Json;

namespace TestJsonNet
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine(JsonConvert.SerializeObject(new Size(50, 50)));
            Console.WriteLine(JsonConvert.SerializeObject(new Size2(50, 50)));
        }
    }

    struct Size2
    {
        public int Width { get; set; }
        public int Height { get; set; }
        public Size2(int w, int h) : this()
        {
            Width = w; Height = h;
        }
    }
}

Outputs the following:

"50, 50"
{"Width":50,"Height":50}

I can understand the thinking behind serializing a struct to a string, since the memory layout is always the same; however, why the discrepancy when serializing a custom struct?

Also, I would (for internal legacy reasons), like to have JSON.Net serialize structs like the latter case (i.e. as JSON, not string). If it's possible, how can that be achieved?

like image 970
Dave T. Avatar asked Dec 10 '12 15:12

Dave T.


People also ask

Is Newtonsoft JSON obsolete?

Yet Newtonsoft. Json was basically scrapped by Microsoft with the coming of . NET Core 3.0 in favor of its newer offering designed for better performance, System. Text.

What is a JSON serialization exception?

The exception thrown when an error occurs during JSON serialization or deserialization.

Is JSON serialized or Deserialized?

JSON is language independent and because of that, it is used for storing or transferring data in files. The conversion of data from JSON object string is known as Serialization and its opposite string JSON object is known as Deserialization.

What is Jsonconvert?

Provides methods for converting between . NET types and JSON types.


1 Answers

Using reflection you could solve this problem. I took part of the solution you suggested yourself and used reflection to get the property names and values.

class StructConverter : JsonConverter
{
    public override void WriteJson(
        JsonWriter writer, object value, JsonSerializer serializer)
    {
        var myObject = (object)value;
        var jObject = new JObject();

        Type myType = myObject.GetType();
        IList<PropertyInfo> props = new List<PropertyInfo>(myType.GetProperties());

        foreach (PropertyInfo prop in props)
        {

            jObject.Add(prop.Name, prop.GetValue(myObject, null).ToString());
        }
        serializer.Serialize(
            writer,  jObject);
    }

....

    public override bool CanConvert(Type objectType)
    {
        return objectType.IsValueType;
    }
}
like image 121
Bert Rymenams Avatar answered Sep 20 '22 20:09

Bert Rymenams