questions/52743860/c-sharp-deserialize-unlabelled-json-array

CSharp · Console

/Program.cs

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.Serialization.Formatters;
using System.IO;
using System.Data;
using System.ComponentModel.DataAnnotations;
using System.Globalization;
using System.Reflection;

using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Newtonsoft.Json.Converters;
using Newtonsoft.Json.Serialization;	

using NUnit.Framework; // Throws NUnit.Framework.AssertionException

//https://stackoverflow.com/questions/52743860/c-sharp-deserialize-unlabelled-json-array

	public class Parsed_JSON {
		public string label1 { get; set; }
		public ICollection<Full_Result> label2 { get; set; }
		public string label3 { get; set; }
		public string label4 { get; set; }
	}

	[JsonConverter(typeof(ObjectToArrayConverter<Full_Result>))]
	public class Full_Result 
	{
		[JsonProperty(Order = 1)]
		public IList<string> values { get; set; }
		[JsonProperty(Order = 2)]
		public float score { get; set; }
	}

	// Taken from this answer:
	// https://stackoverflow.com/a/39462464/3744182
	// to https://stackoverflow.com/questions/39461518/c-sharp-json-net-deserialize-response-that-uses-an-unusual-data-structure

	public class ObjectToArrayConverter<T> : JsonConverter
	{
		public override bool CanConvert(Type objectType)
		{
			return typeof(T) == objectType;
		}

		static bool ShouldSkip(JsonProperty property)
		{
			return property.Ignored || !property.Readable || !property.Writable;
		}

		public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
		{
			var type = value.GetType();
			var contract = serializer.ContractResolver.ResolveContract(type) as JsonObjectContract;
			if (contract == null)
				throw new JsonSerializationException("invalid type " + type.FullName);
			var list = contract.Properties.Where(p => !ShouldSkip(p)).Select(p => p.ValueProvider.GetValue(value));
			serializer.Serialize(writer, list);
		}

		public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
		{
			if (reader.TokenType == JsonToken.Null)
				return null;
			var token = JArray.Load(reader);
			var contract = serializer.ContractResolver.ResolveContract(objectType) as JsonObjectContract;
			if (contract == null)
				throw new JsonSerializationException("invalid type " + objectType.FullName);
			var value = existingValue ?? contract.DefaultCreator();
			foreach (var pair in contract.Properties.Where(p => !ShouldSkip(p)).Zip(token, (p, v) => new { Value = v, Property = p }))
			{
				var propertyValue = pair.Value.ToObject(pair.Property.PropertyType, serializer);
				pair.Property.ValueProvider.SetValue(value, propertyValue);
			}
			return value;
		}
	}

    class TestClass
    {
        public static void Test()
        {
			var JSON = GetJson();
			
			Parsed_JSON result = JsonConvert.DeserializeObject<Parsed_JSON>(JSON);
			
			var newJson = JsonConvert.SerializeObject(result, Formatting.Indented);
			
			Console.WriteLine("Deserialized and re-serialized {0}: ", result);
			
			Console.WriteLine(newJson);
		}
		
		static string GetJson()
		{
			var json = @"{  
    ""label1"": ""value1"",  
    ""label2"": [  
        [  
            [  
                ""concept_id_1"",  
                ""concept_1""  
            ],  
			1
        ],  
        [  
            [  
                ""concept_id_2"",  
                ""concept_2""  
            ],  
			2
        ],  
    ],  
    ""label3"": ""value3"",  
    ""label4"": ""value4""  
}  ";
			return json;
		}
	}

	public class Program
	{
		public static void Main()
		{
			Console.WriteLine("Environment version: " + Environment.Version);
			Console.WriteLine("Json.NET version: " + typeof(JsonSerializer).Assembly.FullName);
			Console.WriteLine();

			try
			{
				TestClass.Test();
			}
			catch (Exception ex)
			{
				Console.WriteLine("Failed with unhandled exception: ");
				Console.WriteLine(ex);
				throw;
			}
		}
	}
;