Runtime: JsonElement - Support Reading As Custom type

Created on 14 Aug 2019  路  6Comments  路  Source: dotnet/runtime

Sugguest addJsonElement.GetObject<T>() like JToken.ToObject<T> that support custom converter.

The json data structure we get from the external api will change depending on the situation, so it cannot be processed using the JsonSerializer.Deserialize method.

The JToken.ToObject<T> method from Json.net suits well. I hope New JSON API can have a equivalent method.

area-System.Text.Json enhancement

Most helpful comment

+1 to this

I have a situation with a { type: string; data: any; } type system. I would like to be able to switch on the type field to then decide how to actually deserialise my data without needing to deserialise the json text twice.

class MyMessage
{
    public string Type;
    public JsonElement Data;
}

With this above I would like to be able to perform the following like I can in json.net

var unknownMessage = JsonSerializer.Deserialize<MyMessage>(input);
switch (unknownMessage.Type)
{
    case "TEST":
        // proposed API which can hopefully be a considerably faster operation
        // since the json is already in an internal DOM
        var data = unknownMessage.Data.ToObject<TestMessageData>(); 
        return data.Something;
}

All 6 comments

so it cannot be processed using the JsonSerializer.Deserialize method.

Can you expand on why that isn't sufficient?

Sugguest addJsonElement.GetObject<T>() like JToken.ToObject<T> that support custom converter.

Can you share sample usage of JToken.ToObject<T> that you have today which uses custom converters? What are you trying to achieve in your scenario?

Thanks

Can you expand on why that isn't sufficient?

For the api like binance(Bitcoin exchange)
It will return either normal data like { "lastUpdateId": 1027024, "bids": [ [ "4.00000000", // PRICE "431.00000000" // QTY ] ], "asks": [ [ "4.00000200", "12.00000000" ] ] }
or error data like {"code":-1015,"msg":"Too many new orders; current limit is 10 orders per 1 SECOND."}

I can not just use JsonSerializer.Deserialize to process the data.

When I am using the JSON.NET ,I will firstly parse it into a JToken and check if json["code"]==null

And while Processing the order detail, i need to return different type of concrete class according to the order type as some field only exists in certain order type.

like the endpoint below.
https://github.com/binance-exchange/binance-official-api-docs/blob/master/rest-api.md#new-order--trade

So i have a IOrder interface and some class like LimitOrder, IOCOrder ....
and use the custom converter to parse all orders.

+1 to this

I have a situation with a { type: string; data: any; } type system. I would like to be able to switch on the type field to then decide how to actually deserialise my data without needing to deserialise the json text twice.

class MyMessage
{
    public string Type;
    public JsonElement Data;
}

With this above I would like to be able to perform the following like I can in json.net

var unknownMessage = JsonSerializer.Deserialize<MyMessage>(input);
switch (unknownMessage.Type)
{
    case "TEST":
        // proposed API which can hopefully be a considerably faster operation
        // since the json is already in an internal DOM
        var data = unknownMessage.Data.ToObject<TestMessageData>(); 
        return data.Something;
}

+1 to this.
Interim use.

public static  class JsonElementExtensions
    {
        public static T Get<T>([NotNull] this JsonElement element)
        {
            if (element.ValueKind == JsonValueKind.Null)
            {
                return default(T);
            }
            if (element.ValueKind == JsonValueKind.Undefined || element.ValueKind == JsonValueKind.Object)
            {
                return JsonSerializer.Deserialize<T>(element.ToString());
            }
            else
            {
                return (T)Convert.ChangeType(element.ToString(), typeof(T));
            }
        }
    }

This scenario can be solved with https://github.com/dotnet/runtime/issues/31274 by reading first as JsonElement, performing validation, then deserialize with the serializer.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

chunseoklee picture chunseoklee  路  3Comments

yahorsi picture yahorsi  路  3Comments

aggieben picture aggieben  路  3Comments

nalywa picture nalywa  路  3Comments

btecu picture btecu  路  3Comments