I have the following data:
Unlike a similair question here: Utf8Json deserialize to type based on marker field the web service does not return the marker field (in the below case primaryExch) as the first item.
Essentially i would like to utf8json decode data into the following:
[
{
"ticker": "AAPL",
"name": "Apple Inc.",
"market": "STOCKS",
"locale": "US",
"currency": "USD",
"active": true,
"primaryExch": "NGS",
"type": "cs",
"codes": {
"cik": "0000320193",
"figiuid": "EQ0010169500001000",
"scfigi": "BBG001S5N8V8",
"cfigi": "BBG000B9XRY4",
"figi": "BBG000B9Y5X2"
},
"updated": "2019-01-15T05:21:28.437Z",
"url": "https://api.polygon.io/v2/reference/tickers/AAPL"
},
{
"ticker": "$AEDAUD",
"name": "United Arab Emirates dirham - Australian dollar",
"market": "FX",
"locale": "G",
"currency": "AUD",
"active": true,
"primaryExch": "FX",
"updated": "2019-01-25T00:00:00.000Z",
"attrs": {
"currencyName": "Australian dollar,",
"currency": "AUD,",
"baseName": "United Arab Emirates dirham,",
"base": "AED"
},
"url": "https://api.polygon.io/v2/tickers/$AEDAUD"
},
{ /* another stock */ },
{ /* another stock */ },
{ /* another FX*/ },
{ /* another stock */ },
{ /* another FX*/ }
/* and so forth */
]
The URL property of hte base type, and currencyName and baseName of the FX type can be skipped as they are not required.
Into the following result:
class Response
{
List<Stocks> Stocks{ get; set; }
List<ForeignExchange> ForeignExchange { get; set; }
}
I would also be OK with a list of base types also List<Ticker> being returned:
class Ticker { string Ticker {get; set;} string Name {get; set;} MarketEnum Market {get; set;} LocaleEnum Locale {get; set;} CurrencyEnum Currency {get; set;} bool Active {get; set;} PrimaryExchEnum PrimaryExch {get; set;} DateTimeOffset Updated {get; set;} }
class Stock : Ticker
{
int Type {get; set;}
string CIK {get; set;}
string FIGIUID {get; set;}
string SCFIGI {get; set;}
string CFIGI {get; set;}
string FIGI {get; set;}
}
class ForeignExchange : Ticker
{
BaseCurrencyEnum BaseCurrency {get; set;}
}
I can see how this is done in JSON.net as per .NET Deserializing JSON to multiple types but after utf8json for the speed but ideally without stacks of low level deserializtion code.
As per my link originally referenced, Utf8Json deserialize to type based on marker field i am unable to use the marker field since it does not come first and unsure of how to deal with this scenario efficiently.
public override List<Ticker> Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
if (reader.TokenType != JsonTokenType.StartArray)
throw new JsonException();
var messages = new List<Ticker>();
while(Expect(ref reader, JsonTokenType.StartObject, JsonTokenType.EndArray))
{
// var message = new Ticker(); // cant do this as i dont know the type yet
while(Expect(ref reader, JsonTokenType.PropertyName, JsonTokenType.EndObject))
switch(reader.GetString())
{
default: throw new JsonException();
case "ticker": /* tickervar */ = ExpectString (ref reader); break;
case "primaryExch": /* primaryExchvar */ = ExpectString (ref reader); break;
case "codes": /* codesvar */ = ExpectStringArray (ref reader); break;
case "attr": /* attrvar */ = ExpectStringArray (ref reader); break;
...
}
if(primaryExchvar == PrimaryExch.FX)
message.Add(new ForeignExchange(tickervar, primaryExch, /* need to add the base from attr);
else
message.Add(new Stock(tickervar, primaryExch, /* need to add the items from codes);
break;
...
}
}
return messages;
}
I could store all deserialized property in a temporary dictionary, but this defeats the whole purpose of zero copy.
Also I am unsure how to flatten codes and attr arrays.
Any pointers much appreciated.