Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Serialize a Json property that is sometimes an array [duplicate]

Tags:

c#

json.net

Is there any way to serialize a Json object property that varies from decimal to decimal[] in a single operation?

In my Json product feed special offer items are represented as an array (normal price/ sale price). Normal items are just the price. Like so:

[
    {
        "product" : "umbrella",
        "price" : 10.50,
    },
        "product" : "chainsaw",
        "price" : [
                      39.99,
                      20.0
                    ]
    }
]

The only way I can get it to work is if I make the property an object like so:

public class Product
{
    public string product { get; set; }
    public object price { get; set; }
}

var productList = JsonConvert.DeserializeObject<List<Product>>(jsonArray);

But if I try to make it decimal[] then it will throw exception on a single decimal value. Making it an object means that the arrays values are a JArray so I have to do some clean up work afterwards and other mapping in my application requires the property type to be accurate so I have to map this to an unmapped property then initialize another property which is no big deal but a little messy with naming.

Is object the only option here or is there some magic I can do with the serializer that either adds single value to array or the second value to a separate property for special offer price?

like image 957
Guerrilla Avatar asked May 10 '15 03:05

Guerrilla


1 Answers

You have to write a custom converter for that price property (because it's not in well format), and use like this:

 public class Product
    {
        public string product { get; set; }
        [JsonConverter(typeof(MyConverter ))]
        public decimal[] price { get; set; }
    }


 public class MyConverter : JsonConverter
    {
        public override bool CanConvert(Type objectType)
        {
            return false;
        }

        public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
        {
            if(reader.TokenType == JsonToken.StartArray)
            {
                return serializer.Deserialize(reader, objectType);
            }
            return new decimal[] { decimal.Parse(reader.Value.ToString()) };              
        }

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

And then parse as normal:

 var productList = JsonConvert.DeserializeObject<List<Product>>(jsonStr);
like image 172
nhabuiduc Avatar answered Oct 11 '22 06:10

nhabuiduc