2

I am in search a method that deserializes an array (without member names) to a C# object. Working and expected examples are provided and I have seen many similar posts but not quite what I am looking for hence why felt to ask out for some assistance.

Do I need to take the approach of implementing custom deserialization or am I missing out something already existing?

    // Deserialize Works This Way
    public class Order
    {
        public string orderNo { get; set; }
        public string customerNo { get; set; }
        public List<List<double>> items { get; set; }
    }

    // Expected Covert Type.
    public class OrderExpected
    {
        public string orderNo { get; set; }
        public string customerNo { get; set; }
        public List<OrderItem> items { get; set; }
    }

    public class OrderItem
    {
        public int itemId { get; set; }
        public decimal price { get; set; }
        public decimal quantity { get; set; }
    }

Code I have tried and what I would like to get working:

     var json = "{\"orderNo\":\"AO1234\",\"customerNo\":\"C0129999\",\"items\":[[255, 1.65, 20951.60],[266, 1.80, 20000.00],[277, 1.90,0.50]]}";
     // Works OK, but ins't what I am after
     var order = JsonConvert.DeserializeObject<Order>(json);

     // I'd like to get some help to get this approch working.
     var orderexpected = JsonConvert.DeserializeObject<OrderExpected>(json);

Further information on items array: The items array is going to consist of arrays which have fixed length of 3 and values represent itemId, price and quantity respectively.

P.S. I am consuming an API which is out of my control.

3

3 Answers 3

4

this can help you..

public class OrderExpected
{
    public string orderNo { get; set; }
    public string customerNo { get; set; }
    public List<OrderItem> items { get; set; }
}

[JsonConverter(typeof(OrderItemConverter))]
public class OrderItem
{
    public int itemId { get; set; }
    public decimal price { get; set; }
    public decimal quantity { get; set; }
}

public class OrderItemConverter : JsonConverter
{

    public override bool CanConvert(Type objectType)
    {
        return objectType.Name.Equals("OrderItem");
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {

        JArray array =  JArray.Load(reader);
        return new OrderItem { 
            itemId = array[0].ToObject<int>(),
            price = array[1].ToObject<decimal>(),
            quantity = array[2].ToObject<decimal>()
        }; 
    }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        var orderItem = value as OrderItem;
        JArray arra = new JArray();
        arra.Add(orderItem.itemId);
        arra.Add(orderItem.price);
        arra.Add(orderItem.quantity);
        arra.WriteTo(writer);
    }
}

using..

        string jsonString = "{\"orderNo\":\"AO1234\",\"customerNo\":\"C0129999\",\"items\":[[255, 1.65, 20951.60],[266, 1.80, 20000.00],[277, 1.90,0.50]]}";
        var objectResult = JsonConvert.DeserializeObject<OrderExpected>(jsonString);
        var serializationResult = JsonConvert.SerializeObject(objectResult);
        Console.WriteLine(serializationResult);
        // output : {"orderNo":"AO1234","customerNo":"C0129999","items":[[255,1.65,20951.6],[266,1.8,20000.0],[277,1.9,0.5]]}
Sign up to request clarification or add additional context in comments.

1 Comment

slick and complete solution. Thanks!
1

You can use custom JsonConverter for specified property by using attribute: JsonConverter(typeof(YourCustomConverter))

In your case simple examle should looks like this:

public class OrderExpected
{
    public string OrderNo { get; set; }
    public string CustomerNo { get; set; }
    [JsonConverter(typeof(OrderItemConverter))]
    public List<OrderItem> Items { get; set; }
}

public class OrderItemConverter : JsonConverter
{
    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        throw new NotImplementedException();
    }

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

        var jArray = JArray.Load(reader);
        var result = new List<OrderItem>();
        foreach (var arrayItem in jArray)
        {
            var innerJArray = arrayItem as JArray;
            if(innerJArray?.Count != 3)
                continue;

            result.Add(new OrderItem
            {
                ItemId = (int) innerJArray[0],
                Price = (decimal)innerJArray[1],
                Quantity = (decimal)innerJArray[2]
            });
        }

        return result;
    }

    public override bool CanConvert(Type objectType)
    {
        throw new NotImplementedException();
    }
}

And deserialize your json as usual.

var obj = JsonConvert.DeserializeObject<OrderExpected>(json);

Comments

0

Alright, I agree with Levent. I just want to develop this answer! in Json.Net side use this attribute [JsonExtensionData] when Json string contains properties without property names

[Serializable]
[JsonObject]
public class Price
{
    [JsonExtensionData]
    public IDictionary<string, JToken> Values { get; set; }
    [JsonProperty("vendor")]
    public Dictionary<string, string> vendor { get; set; }
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.