JSON https://api.smarkets.com/v3/markets/9091412/quotes/

Hi,
I can’t deserialize the json produced by the call:
curl -X GET “https://api.smarkets.com/v3/markets/9091412/quotes/” -H “accept: application/json”

Where 9091412 is the WIN market relating to Kempton 20:30 horse racing 22 October 2019
Specifically, unlike all the other calls that produce json that I can deserialize, the one related to quotes requires that for id_contract there is directly the id_contract value without the parameter name being specified.
There is not the usual name = value but only the value.
I paste a part of the json string (the first two horses). Could someone tell me in c # how to perform deserialization?

{“31669198”: {“bids”: [{“price”: 62, “quantity”: 7917031}, {“price”: 48, “quantity”: 10213781},
{“price”: 45, “quantity”: 10870210}]
, “offers”: [{“price”: 91, “quantity”: 193727}, {“price”: 100, “quantity”: 1041001},
{“price”: 182, “quantity”: 794486}, {“price”: 312, “quantity”: 8012821}]}
,“31669201”: {“bids”: [{“price”: 1042, “quantity”: 9397784},
{“price”: 1020, “quantity”: 9705882}, {“price”: 952, “quantity”: 22717283},
{“price”: 909, “quantity”: 2248703}, {“price”: 667, “quantity”: 3108792}]
, “offers”: [{“price”: 1087, “quantity”: 784354}, {“price”: 1136, “quantity”: 2200704},
{“price”: 1220, “quantity”: 4426229}, {“price”: 1250, “quantity”: 573812},
{“price”: 1389, “quantity”: 809938}]}}

Hi Andrea,

I’m not familiar with C#, so the following code may not be the best solution, but it works.

using System.Net;
using System.Collections.Generic;
using System.IO;
using System.Web;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Newtonsoft.Json.Converters;
using Newtonsoft.Json.Serialization;

class MyConverter : CustomCreationConverter<IDictionary<string, object>>
{
	public override IDictionary<string, object> Create(Type objectType)
	{
		return new Dictionary<string, object>();
	}

	public override bool CanConvert(Type objectType)
	{
		// in addition to handling IDictionary<string, object>
		// we want to handle the deserialization of dict value
		// which is of type object
		return objectType == typeof(object) || base.CanConvert(objectType);
	}

	public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
	{
		if (reader.TokenType == JsonToken.StartObject || reader.TokenType == JsonToken.Null)
			return base.ReadJson(reader, objectType, existingValue, serializer);
		// if the next token is not an object
		// then fall back on standard deserializer (strings, numbers etc.)
		return serializer.Deserialize(reader);
	}
}

public class Program
{
	public static void Main()
	{
		WebClient client = new WebClient();
		var response = client.DownloadString("https://api.smarkets.com/v3/markets/9091412/quotes/");
		Console.WriteLine(response);
		var dict = JsonConvert.DeserializeObject<IDictionary<string, object>>(response, new JsonConverter[]{new MyConverter()});
		foreach (KeyValuePair<string, object> item in dict)
		{
			Console.WriteLine("Key: {0}, Value: {1}", item.Key, item.Value);
		}
	}
}

Hope it helps,
Isabel

Hi Andrea,

Did you find a better way of doing this rather than Isabel’s? I don’t understand why they would not include the name of the attribute and just start with a value. This stops us from using a DataMember to deserialize the call.