C# - deserialize JSON into ValueTuple

json deserialize tuple c#
c# json serialize named tuple
newtonsoft json serialize
deserialize json to tuple
json deserialize generic type c#
system.text.json jsonconverter
c# json parse tuple
newtonsoft json serialize array

I'm trying to deserialize [{"foo": "1", "bar": false}, {"foo": "2", "bar": false}] into List<(string, bool)> type:

JsonConvert.DeserializeObject<List<(string foo, bool bar)>>(json)  

But always get a list of default values - (null, false).

How can I achieve correct deserializing?

P.S. I'm not interested in any model/class for that purpose. I need exactly value tuple instead.


One way to achieve it would be to use a JsonConverter. For example,

public class ValueTupleConverter<U,V> : Newtonsoft.Json.JsonConverter
{
    public override bool CanConvert(Type objectType)
    {
        return typeof(ValueTuple<U,V>) == objectType;
    }

    public override object ReadJson(Newtonsoft.Json.JsonReader reader,Type objectType,object existingValue,Newtonsoft.Json.JsonSerializer serializer)
    {
        if (reader.TokenType == Newtonsoft.Json.JsonToken.Null) return null;

        var jObject = Newtonsoft.Json.Linq.JObject.Load(reader);
        var properties = jObject.Properties().ToList();
        return new ValueTuple<U, V>(jObject[properties[0].Name].ToObject<U>(), jObject[properties[1].Name].ToObject<V>());
    }

    public override void WriteJson(Newtonsoft.Json.JsonWriter writer, object value, Newtonsoft.Json.JsonSerializer serializer)
    {
        serializer.Serialize(writer, value);
    }

}

Now you can use the Converter as following.

var json = "[{'foo': '1', 'bar': false}, {'foo': '2', 'bar': false}]";
var result = JsonConvert.DeserializeObject<IEnumerable<(string,bool)>>(json,new ValueTupleConverter<string,bool>());
foreach(var (foo,bar) in result)
{
   Console.WriteLine($"foo:{foo},bar:{bar}");
}

Sample Output

foo:1,bar:False
foo:2,bar:False

C#7 Tuple Support � Issue #1230 � JamesNK/Newtonsoft.Json � GitHub, I've managed to achieve ValueTuple de/serialization, with the caveat that you have to explicitly declare the ValueTuples in the signature of Value� To deserialize from a file by using synchronous code, read the file into a string, as shown in the following example: jsonString = File.ReadAllText(fileName); weatherForecast = JsonSerializer.Deserialize<WeatherForecast>(jsonString);


The C# tuple feature was created to represent sets of values, not entities.

The names of the values are like the names of variables. Like variable names, tuple value names only exist in source code.

(string foo, bool bar) is, actually, just ValueTuple<string, int>. just like (string bar, bool foo):

(string foo, bool bar) a = ('one', true);
(string bar, bool foo) b = a;

The tuple values are stored in fields named Item1, Item2 and so on.

See for yourself how it works here.

If you're that keen into using value tuples for that, you'll have to deserialize yourself:

var json = "[{\"foo\": \"1\", \"bar\": false}, {\"foo\": \"2\", \"bar\": false}]";

var jArray = JsonConvert.DeserializeObject<JArray> (json);

var list = new List<(string foo, bool bar)>();

foreach (var item in jArray)
{
    list.Add((item.Value<string>("foo"), item.Value<bool>("bar")));
}

System.Text.Json can not deserialize/serialize ValueTuple � Issue , When trying to serialize ValueTuple to Json gives an empty object "{}" Works with Tuple but not ValueTuple. Choose one of the following approaches: Add an instance of the converter class to the JsonSerializerOptions.Converters collection. Apply the [JsonConverter] attribute to the properties that require the custom converter. Apply the [JsonConverter] attribute to a class or a struct that represents a custom value type.


I suggest first convert the JSON to model and Deserialize the json

public class item
{
    public string foo { get; set; }
    public bool bar { get; set; }
}

Method 1 - using foreach

using (StreamReader r = new StreamReader(filepath))
{
     string json = r.ReadToEnd();
     var obj = JsonConvert.DeserializeObject<List<item>>(json);

     Dictionary<string, bool> keyValuePairs = new Dictionary<string, bool>();
     foreach (var keyvalue in obj)
     {
          if (!keyValuePairs.ContainsKey(keyvalue.foo))
             keyValuePairs.Add(keyvalue.foo, keyvalue.bar);
     }
}

Method 2 - using LINQ without worrying about duplicates

Dictionary<string, bool> keyValuePairs = JsonConvert.DeserializeObject<IEnumerable<item>>(json).ToDictionary(x => x.foo, x => x.bar);

Method 3 - using LINQ by considering duplicates

Dictionary<string, bool> keyValuePairs = JsonConvert
                .DeserializeObject<IEnumerable<item>>(json)
                .GroupBy(p=>p.foo, StringComparer.OrdinalIgnoreCase)
                .ToDictionary(x => x.First().foo, x => x.First().bar);

Method 4 - using DeserializeAnonymousType

 var definition = new[] {new { foo = "", bar = false } };
 string json = @"[{'foo': '1', 'bar': false}, {'foo': '2', 'bar': true}]";
 var obj = JsonConvert.DeserializeAnonymousType(json, definition).Select(p=> (p.foo, p.bar)).ToList();

Migrate from Newtonsoft.Json to System.Text.Json, ValueTuple and its associated generic types. Custom converters can be implemented for types that don't have built-in support. Quoted numbers. In Deserialization, it does the opposite of Serialization which means it converts JSON string to custom .Net object. In the following code, it calls the static method DeserializeObject () of the JsonConvert class by passing JSON data. It returns a custom object (BlogSites) from JSON data. string json = @" {.


JSON Deserializing a tuple of enums : csharp, Now, json.net serializes this all right, but it fails to deserialize it. public enum EAge ValueTuple`3[JsonEnumSerialization. But if TKey is not a string or number, the built-in Newtonsoft stuff won't be able to deserialize what it serializes . For Json.NET, we would just need to add overloads to JsonConvert.SerializeObject, JsonConvert.DeserializeObject, JsonSerializer.Serialize, and JsonSerializer.Deserialize to accept an array of strings for the tuple element names. Do you think this would be worth proposing to the C# language design team? 👍


Serializing/Deserializing Dictionaries with Tuple as Key , One such example is when you attempt to serialize/Deserialize a above code would trow an JsonSerializationException when deserializing. IL_0000: nop // Do nothing (No operation) IL_0001: ldarg.0 // Load argument 0 onto the stack IL_0002: call instance valuetype [System.ValueTuple]System.ValueTuple`2<string, int32> C::GetPerson() // Call method indicated on the stack with arguments IL_0007: stloc.0 // Pop a value from stack into local variable 0 IL_0008: ldloc.0 // Load local


Deserialize an Anonymous Type, This sample deserializes JSON into an anonymous type. Sample. Usage. Copy. var definition = new { Name = "" }; string json1 = @"{'Name':'James'}"; var� Sometimes you run into things that might look trivial but it just do not work as expected. One such example is when you attempt to serialize/Deserialize a Dictionary with Tuples as the key. For example The above code would trow an JsonSerializationException when deserializing. But the good part is, the exception tells you exactly what…