9

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?

1
  • 1
    I did find this article JSON.NET serialization trouble, however I would still like to turn off this behavior for all struct types at one fell swoop. Commented Dec 10, 2012 at 15:52

1 Answer 1

2

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;
    }
}
Sign up to request clarification or add additional context in comments.

3 Comments

The real answer to my question is: you can't. There's no way to configure JSON.NET so that it uses its own converter instead of the TypeConverter. But, I'll give you the check (and necromancer badge?) since it's probably the most generic.
Thanks Dave. I wonder if there are JSON serializers for .net out there that do this out of the box.
Yes, there are. Have a look to ServiceStack.Text. If you provide two functions Parse and ToString to a struct, it take those in order to deserialize and serialize. I find it quite useful.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.