How does a Tuple serialize to and deserialize from JSON?

C#Json

C# Problem Overview


I am curious about how the Tuple<T1, T2, T3, ...> serializes and deserializes. I searched using keywords "json" and "tuple" but I could not find what I want.

C# Solutions


Solution 1 - C#

I test by UnitTest and Json.net, and the test codes is as following. The results shows Tuple<T1,T2,T3,...> is serializable and deserializable. So I can use them in my application.

Test codes
public class Foo {
    public List<Tuple<string, string, bool>> Items { get; set; }

    public Foo()
    {
        Items = new List<Tuple<string, string, bool>>();
    }

    public override string ToString()
    {
        StringBuilder sb = new StringBuilder();
        foreach (var a in Items)
        {
            sb.Append(a.Item1 + ", " + a.Item2 + ", " + a.Item3.ToString() + "\r\n");
        }
        return sb.ToString();
    }
}

[TestClass]
public class NormalTests
{
    [TestMethod]
    public void TupleSerialization()
    {
        Foo tests = new Foo();
        
        tests.Items.Add(Tuple.Create("one", "hehe", true));
        tests.Items.Add(Tuple.Create("two", "hoho", false));
        tests.Items.Add(Tuple.Create("three", "ohoh", true));

        string json = JsonConvert.SerializeObject(tests);
        Console.WriteLine(json);

        var obj = JsonConvert.DeserializeObject<Foo>(json);
        string objStr = obj.ToString();
        Console.WriteLine(objStr);
    }
}
Summary
  • Tuple.Create("own","hehe",true) serializes to {"Item1":"one","Item2":"hehe","Item3":true}

  • {"Item1":"one","Item2":"hehe","Item3":true} can be deserialized back to Tuple<string,string, bool>

  • Class Foo with Tuple data, can be serialized to json string, and the string can be deserialized back to Class Foo.

Solution 2 - C#

If you are looking for a short answer. I am using JsonConvert.

var testTuple = Tuple.Create(1234, "foo", true);
var serialized = JsonConvert.SerializeObject(testTuple);

Console.WriteLine(serialized);
// prints: {"Item1":1234,"Item2":"foo","Item3":true}

I made a minimal fiddle.

Solution 3 - C#

With .NET5 and soon .NET6 it's now recommended to use System.Text.Json over NewtonSoft. The important thing for this serializer with regard to tuples is to set the JsonSerializerOptions option IncludeFields, as otherwise tuple values are excluded by default.

Further, named tuples are just syntactic sugar which are replaced by standard Item1, Item2 notation by the compiler. To include names the simplest way is to use an anonymous object.

Below is a minimal example. (can paste into .NET fiddle with the .NET5 compiler)


using System;
using System.Collections.Generic;
using System.Text.Json;
                    
public class Program
{
    public static void Main()
    {
        JsonSerializerOptions options = new() { IncludeFields = true };

        var testTuple = ("test" , "test1", 1324, false);
        var serializedTuple = JsonSerializer.Serialize(testTuple, options);
        Console.WriteLine(serializedTuple);
		
		var testTuple2 = (NamedItem1: "test" , NamedItemTwo: "test1", TheIntegersName: 1324, ThisBoolHasAFirstNameIts: false);
        var serializedTuple2 = JsonSerializer.Serialize(new {testTuple2.NamedItem1, testTuple2.NamedItemTwo, testTuple2.TheIntegersName, testTuple2.ThisBoolHasAFirstNameIts }, options);
        Console.WriteLine(serializedTuple2);
		
    }
}

output:

{"Item1":"test","Item2":"test1","Item3":1324,"Item4":false}

{"NamedItem1":"test","NamedItemTwo":"test1","TheIntegersName":1324,"ThisBoolHasAFirstNameIts":false}

Solution 4 - C#

Thank you Hinrich to the dotnetfiddle link above.

i used the same link, and got to know how Conversion works between Json objects and Tuples. Below is the code :

using System;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
					
public class Program
{
	public static void Main()
	{
		
		var testTuple = Tuple.Create<int, string, bool>(1234, "foo", true);
		var serialized = JsonConvert.SerializeObject(testTuple);
		Console.WriteLine(serialized);
		JObject test = ((JObject)JsonConvert.DeserializeObject(serialized));
		string strSerialized = JsonConvert.SerializeObject(test);
		//Tuple<int, string, bool> testTuple1 = JsonConvert.DeserializeObject<Tuple<int, string, bool>>(serialized); // WORKs
		Tuple<int, string, bool> testTuple1 = JsonConvert.DeserializeObject<Tuple<int, string, bool>>(strSerialized); // WORKs
		Console.WriteLine(testTuple1.Item1.ToString());
	}
}

Hope someone finds this helpful.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionAechoLiuView Question on Stackoverflow
Solution 1 - C#AechoLiuView Answer on Stackoverflow
Solution 2 - C#HinrichView Answer on Stackoverflow
Solution 3 - C#TheAtomicOptionView Answer on Stackoverflow
Solution 4 - C#user13230141View Answer on Stackoverflow