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.
4 Answers
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 toTuple<string,string, bool>
Class Foo
withTuple
data, can be serialized to json string, and the string can be deserialized back toClass Foo
.

- 17,522
- 9
- 100
- 118
-
1Funny thing: it'd seem to fail for types inheriting Tuple – eglasius Mar 31 '16 at 12:57
-
Another funny thing: You need to write your own [JsonConverter](https://www.newtonsoft.com/json/help/html/CustomJsonConverter.htm) in order to deal with inheritance in some cases. – Anastasios Moraitis Apr 30 '20 at 07:42
-
Another funny thing: What if you try with Tuple
being T1 and/or T2 non-serializable? You can only assume it is serializable if is a tuple of serializable types. – Windgate Feb 28 '22 at 09:39
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.

- 13,485
- 7
- 43
- 66
-
2I honestly think that this answer is more helpful than the top-voted answer. It's much clearer and direct to say that a `Tuple
` serializes to `{Item1: string, Item2: string}`, than what the top-voted answerer has as their answer. – Andrew Gray Feb 24 '20 at 20:21 -
5I suspect it's because the OP's answer had five years to gather upvotes before this answer :) – Jag Nov 04 '20 at 11:07
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}

- 1,456
- 1
- 12
- 21
-
2Is there a way to change the naming of the tuple items from `ItemN` to the custom name in the code? For example: `(int x, int y) point` should output `"point": { "x": 3, "y": 6 }` instead of `"point": { "Item1": 3, "Item2": 6 }`. – cvbattum Nov 07 '21 at 12:35
-
It's only sort of possible because named tuples are just syntactic sugar so the names aren't retained at compile time for use at runtime (see this answer to a similar question: https://stackoverflow.com/a/57217505/3626160). The simplest workaround is to put the named tuple values into an anonymous object first, as in this answer (https://stackoverflow.com/a/66386667/3626160). I'll update my answer to include this example. – TheAtomicOption Nov 08 '21 at 16:33
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.

- 11
- 1